![]() ![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() ![]() ![]() ![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() |
![]()
1 Informations générales à propos de MySQLCeci est la manuel de référence de MySQL; il correspond à la version 3.23.2-alpha de MySQL. MySQL est un langage rapide, multi-threaded, multi-utilisateur, c'est aussi un serveur de base de données SQL robuste (Structured Query Language). Pour les plates-formes Unix et OS/2, MySQL est libre; pour les plates-formes Microsoft il est nécessaire d'acquitter une licence après un temps d'essai de 30 jours. 3 Support et licences MySQL). The MySQL home page fournit les dernières informations concernant MySQL. Pour une description des capacités de MySQL, 1.4 Caractéristiques de MySQL. Pour les instructions d'installation, cf. section G Commentaires sur le portage vers d'autres systèmes d'exploitation. Pour une information sur la mise à jour de la version 3.21, 4.16.2 Mise à jour de a 3.21 vers 3.22. Pour un exemple complet, 8 Exemple MySQL. Pour des informations sur SQL et les benchmark, reportez vous au dossier de benchmark. Dans les distributions source, il est situé dans le dossier ``bench'' . Dans les distributions compilées, il est situé dans le dossier ``sql-bench'' Pour un historique des caractéristiques et des bogues corrigés, D Historique des versions de MySQL. Pour une liste des bogues connus et des lacunes de MySQL, E Erreurs connues et manques de MySQL. Pour les prochaines fonctionnalités, F Liste de voeux pour les versions futures de MySQL (la TODO). Pour la liste de tous les contributeurs à ce produit, C Contributions à MySQL. IMPORTANT: Envoyer les bugs ou erreurs, questions ou commentaires à la liste de diffusion : mysql@lists.mysql.com. 2.3 Comment rapporter des bugs et des problèmes.
Dans les distributions source, le script
Si vous avez des suggestions concernant les ajouts de fonctionnalités ou corrections à ce manuel, envoyer les à la liste de diffusion (en anglais) (@email:{mysql@lists.mysql.com}), avec le sujet suivant : 1.1 Qu'est ce que MySQL?
MySQL est un véritable serveur de base de données SQL multi-utilisateur et multi-threaded. SQL est le plus populaire langage de base de données dans le monde. MySQL est une configuration client/serveur ce qui consiste en un serveur démon SQL est un langage standardisé qui rend facile le stockage, la mise à jour et l'accès à l'information. Par exemple, vous pouvez utiliser le SQL pour récupérer des informations sur un produit ou stocker des informations client sur un site web. MySQL est suffisamment rapide et flexible pour gérer des historiques et des images. Les principaux objectifs de MySQL sont la rapidité, la robustesse et la facilité d'utilisation. MySQL a été originellement développé parce que nous au TcX avions besoin d'un serveur SQL qui puisse gérer des grandes bases de données de manière plus rapide que ce que pouvaient offrir les distributeurs de bases de données. Nous utilisons donc MySQL depuis 1996 dans un environnement de plus de 40 bases de données contenant 10,000 tables, dont plus de 500 contiennent plus de 7 millions d'enregistrements. C'est environ 100 giga octets de données critiques. La base sur laquelle MySQL est construite est un ensemble de routines qui ont été largement éprouvées pendant des années dans un environnement de production exigeant. Même si MySQL est encore en développement, il propose déjà un ensemble de fonctionnalités riches et extrêmement utiles. La prononciation classique de MySQL est ``Maille Ess Ku Ell'' 1.2 A propos de ce manuelCe manuel est actuellement disponible en Texinfo, texte plein, Info, HTML, PostScript and PDF versions. A cause de leur taille, les versions en PostScript et PDF ne sont pas inclues dans la distribution principale de MySQL, mais sont disponibles sur http://www.mysql.com.
Le document initial est le fichier Texinfo. La version HTML a été générée automatiquement avec une version modifiée de La version américaine de ce manuel a été écrite et mise à jour par David Axmark, Michael (Monty) Widenius, Paul DuBois and Kim Aldale. Pour les autres contributeurs, cf. section C Contributions à MySQL. 1.2.1 Conventions utilisées dans ce manuelCe manuel utilise certaines conventions typographiques :
Lorsque les commandes sont décrites et doivent être exécutées par un programme spécifique, le programme est indiquée par le prompt avec la commande. Par exemple, shell> Tapez une commande shell ici mysql> Tapez une commande mysql ici
Les commandes Shell décrites utilisent la syntaxe shell Bourne. Si vous utilisez un shell Par exemple, la séquence de mise à jour d'une variable d'environnement et d'exécution d'une commande se présente comme suit dans la syntaxe Bourne: shell> VARNAME=value some_command
pour shell> setenv VARNAME value shell> some_command
Les noms de base de données, tables et colonnes sont souvent utilisés dans des commandes. Pour indiquer ces utilisations le manuel utilise la convention suivante, mysql> SELECT nom_colonne FROM nom_base_de_donnees.nom_table; Cela signifie que si vous devez utiliser une déclaration similaire, vos utiliserez vos propres noms de base de données, de tables et de colonnes, peut-être comme ceci : mysql> SELECT nom_auteur FROM biblio_db.liste_auteur; Les déclarations SQL peuvent être écrites en majuscules ou minuscules. Lorsque ce manuel montre une expression SQL, les majuscules sont utilisées pour les mots clefs en cours de discussion et les minuscules pour le reste de l'expression. Donc vous pourrez voir ce qui suit pour la déclaration du SELECT: mysql> SELECT count(*) FROM nom_table;
D'autre part, si il s'agit de la fonction mysql> select COUNT(*) from nom_table; Dans le cas où aucun mot clef n'est à souligner, l'expression est en majuscule. Dans la description de la syntaxe d'une expression, les crochets (``['' et ``]'') sont utilisés pour indiquer les options: DROP TABLE [IF EXISTS] nom_table Lorsque les éléments syntaxiques consistent en un certain nombres d'alternatives, les alternatives sont séparés par des barres verticales (``|''). Quand un membre d'un ensemble de possibilités peut être choisit, les possibilités sont listées à l'intérieure de crochets. Quand un membre doit être choisit, les possibilités sont listées à l'intérieure de (``{'' and ``''}): TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str) {DESCRIBE | DESC} nom_table {nom_colonne | wild} 1.3 Historique de MySQL
Nous avions l'intention d'utiliser La dérivation du nom MySQL n'est pas parfaitement claire. Notre arborescence et un certain nombre de nos librairies et outils commencaient par le préfixe "My" depuis des années. Même si la soeur de Monty (il y a quelques années) était surnommée My. A part les deux anecdotes le nom de MySQL est encore un mystère, pour nous aussi. 1.4 Caractéristiques de MySQLLa liste suivante décrit quelques caractéristiques importantes de MySQL:
1.5 Est ce que MySQL est stable?Cette section répond aux questions "Qu'elle est la stabilité de MySQL?'' et, ``Puis-je faire confiance à MySQL sur ce projet?''. Nous allons essayer de clarifier quelques problèmes et répondre aux questions les plus importantes qui concernent une majorité de personnes. Cette section rassemble les informations récoltées dans la liste de diffusion (qui est très active dans l'identification des bogues). A TcX, MySQL fonctionne depuis mi-1996 sans aucun problème. Lorsque MySQL a été diffusé auprès du grand public, un certain nombre de codes n'avaient pas été testés et ils ont été vite identifiés par les nouveaux utilisateurs qui ont utilisé les requêtes d'une manière différente de la notre. Chaque nouvelle release a moins de problèmes de portabilité que la précédente (même si à chaque fois de nouvelles fonctionnalités sont identifiées), et nous espérons bientôt qu'une prochaine version sera labellisée "Stable". Chaque release de MySQL est utilisable et il n'y a de problèmes uniquement lorsque les utilisateurs commencent à utiliser les "zones d'ombres". Naturellement, il est difficile de connaître le contenu de ces zones d'ombres; cette section a pour objectif d'identifier les zones connues. La description concerne la version 3.22.x de MySQL. Tous les bogues connus sont corrigés dans la dernière version, à l'exception de la liste des bogues répertoriés dans la section des erreurs. Cf. section E Erreurs connues et manques de MySQL. MySQL est décomposé en plusieurs couches et différents modules indépendants. Les modules sont listés ci-dessous avec leur état de stabilité :
TcX fournit un support payant par email, cependant la mailing liste MySQL répond à la plupart des questions. Les bogues sont en général corrigés par des patchs; pour les bogues plus importants, il y a de nouvelles versions. 1.6 Compatibilité an 2000MySQL lui-même n'a pas de problémes avec la compatibilité An 2000 (Y2K):
Vous pouvez avoir des problèmes avec des applications qui utilisent MySQL mais non compatible An 2000. Malheureusement ces problèmes sont difficilement corrigibles lorsque ces applications sont écrites par différents programmeurs et que chacun utilise ses propres conventions pour gérer les dates. Vous trouverez ci-après une démonstration simple qui illustre le fait que MySQL n'a aucun problème avec les dates jusqu'en 2030! mysql> DROP TABLE IF EXISTS y2k; mysql> CREATE TABLE y2k (date date, date_time datetime, time_stamp timestamp); mysql> INSERT INTO y2k VALUES ("1998-12-31","1998-12-31 23:59:59",19981231235959); mysql> INSERT INTO y2k VALUES ("1999-01-01","1999-01-01 00:00:00",19990101000000); mysql> INSERT INTO y2k VALUES ("1999-09-09","1999-09-09 23:59:59",19990909235959); mysql> INSERT INTO y2k VALUES ("2000-01-01","2000-01-01 00:00:00",20000101000000); mysql> INSERT INTO y2k VALUES ("2000-02-28","2000-02-28 00:00:00",20000228000000); mysql> INSERT INTO y2k VALUES ("2000-02-29","2000-02-29 00:00:00",20000229000000); mysql> INSERT INTO y2k VALUES ("2000-03-01","2000-03-01 00:00:00",20000301000000); mysql> INSERT INTO y2k VALUES ("2000-12-31","2000-12-31 23:59:59",20001231235959); mysql> INSERT INTO y2k VALUES ("2001-01-01","2001-01-01 00:00:00",20010101000000); mysql> INSERT INTO y2k VALUES ("2004-12-31","2004-12-31 23:59:59",20041231235959); mysql> INSERT INTO y2k VALUES ("2005-01-01","2005-01-01 00:00:00",20050101000000); mysql> INSERT INTO y2k VALUES ("2030-01-01","2030-01-01 00:00:00",20300101000000); mysql> INSERT INTO y2k VALUES ("2050-01-01","2050-01-01 00:00:00",20500101000000); mysql> SELECT * FROM y2k; +------------+---------------------+----------------+ | date | date_time | time_stamp | +------------+---------------------+----------------+ | 1998-12-31 | 1998-12-31 23:59:59 | 19981231235959 | | 1999-01-01 | 1999-01-01 00:00:00 | 19990101000000 | | 1999-09-09 | 1999-09-09 23:59:59 | 19990909235959 | | 2000-01-01 | 2000-01-01 00:00:00 | 20000101000000 | | 2000-02-28 | 2000-02-28 00:00:00 | 20000228000000 | | 2000-02-29 | 2000-02-29 00:00:00 | 20000229000000 | | 2000-03-01 | 2000-03-01 00:00:00 | 20000301000000 | | 2000-12-31 | 2000-12-31 23:59:59 | 20001231235959 | | 2001-01-01 | 2001-01-01 00:00:00 | 20010101000000 | | 2004-12-31 | 2004-12-31 23:59:59 | 20041231235959 | | 2005-01-01 | 2005-01-01 00:00:00 | 20050101000000 | | 2030-01-01 | 2030-01-01 00:00:00 | 20300101000000 | | 2050-01-01 | 2050-01-01 00:00:00 | 00000000000000 | +------------+---------------------+----------------+ 13 rows in set (0.00 sec) mysql> DROP TABLE y2k;
Cela montre que le type Même si MySQL est compatible An 2000, il est de votre responsabilité de fournir une entrée correcte. 7.2.6.1 Bug de l'an 2000 et données de types date pour les règles appliquées par MySQL pour la gestion des entrées ambiguÎs de données (Donnée contenant des valeurs sur 2-digit). 1.7 Informations sur le SQLCes livres ont été recommandés par plusieurs personnes sur la liste de diffusion MySQL : Judith S. Bowman, Sandra L. Emerson et Marcy Darnovsky The Practical SQL Handbook: Using Structured Query Language Second Edition Addison-Wesley ISBN 0-201-62623-3 http://www.awl.com Celui-ci aussi a eu quelques recommandations sur la liste de diffusion : Martin Gruber Understanding SQL ISBN 0-89588-644-8 Publisher Sybex 510 523 8233 Alameda, CA USA Un tutorial SQL est disponible sur http://www.geocities.com/ResearchTriangle/Node/9672/sqltut.html SQL in 21 Tagen (Livre en Allemand ): http://www.mut.de/leseecke/buecher/sql/inhalt.htm 1.8 Liens utiles1.8.1 Outils de développement WEB qui supportent MySQL.
1.8.2 Serveurs Web avec des outils MySQL.1.8.3 Exemples et sources
1.8.4 Liens ODBC.1.8.5 Liens API.
1.8.6 Clients et applications.
1.8.7 Autres liens MySQL.
1.8.8 SQL et interfaces pour bases de données.
1.8.9 Liens sur les bases de données.
Il y a beaucoup de sites Web qui utilisent MySQL. Cf. section A Quelques utilisateurs MySQL. 2 La liste de diffusion MySQL et comment rapporter des bugs2.1 Les listes de diffusion MySQLPour s'incrire sur la liste de diffusion (en anglais) de MySQL, envoyez un message à l'adresse suivante : mysql-subscribe@lists.mysql.com. Pour se désinscrire de la liste de diffusion MySQL, envoyez un message à l'adresse suivante : mysql-unsubscribe@lists.mysql.com. Seule l'adresse d'origine de votre message sera utilisée. Le sujet et le contenu du mail sont ignorés.
Si votre adresse de réponse n'est pas valide, vous pouvez la spécifier explicitement.
Vous pouvez alors ajouter un signe tiret `-', suivi de votre adresse, dont l'arobase
`@' a été remplacé par `='. Par exemple, pour inscrire l'adrsse Les mails envoyés à mysql-subscribe@lists.mysql.com ou mysql-unsubscribe@lists.mysql.com sont gérés automatiquement par le robot de la liste, ezmlm. Des informations à propos de ezmlm sont disponibles à the ezmlm Website.
Pour envoyer un message à la liste elle même, envoyez votre message à
Votre site local peut disposer de sa propre base d'utilisateurs de mysql@lists.mysql.com.
Dans ce cas, il a peut être sa propre liste de diffusion, qui relaient les messages de Les listes de diffusions suivantes existent :
Vous vous inscrivez ou désincrivez de ces listes de la même manière que décrit ci dessus.
Dans votre message, utilisez simplement l'adresse de la liste qui vous interesse, plutôt que
2.2 Poser des questions et rapporter des bugsAvant d'envoyer un rapport de bug, ou une question, suivez les instructions suivantes :
Si vous ne trouvez pas d'information dans le manuel, ou dans les pages d'archives, vérifiez avec votre expert MySQL local. Si vous ne pouvez trouver aucune réponse, passez à la section suivante pour savoir comment envoyer un message à mysql@lists.mysql.com. 2.3 Comment rapporter des bugs et des problèmesEcrire un rapport de bug nécessite de la patience, mais ce premier geste va économiser votre temps, et le notre. Cette section vous aide à écrire votre rapport de bug correctement, de manière à ce que vous ne perdiez pas votre temps à écrire des messages qui ne nous servirons à rien.
Nous vous encourageons à utiliser le script
Le script Gardez à l'esprit qu'il est toujours possible de répondre à un message qui contient trop d'information, alors que ce n'est pas possible avec un message qui en contient pas assez. Souvent, les rapports omettent des informations car les utilisateurs pensent avoir compris les causes du problème et que certains détails sont insignifiants. Le bon principe est le suivant : Si vous doutez de quelque chose, dites le. Il est milles fois plus rapide d'ajouter quelques lignes dans votre rapport, plutôt que d'être forcé de le renvoyé encore une fois, pour complément d'information. L'erreur la plus répandue est que les utilisateurs n'indique pas le numéro de version de la distribution MySQL qu'ils utilisent, ou la plate forme sur laquelle ils opèrent (y compris la version de cette plate forme). C'est une information primordiale, et 99% des cas sont inexploitables sans cette information. Souvent, nous avons des questions du genre : ``Pourquoi est ce que ça plante chez moi?'' et nous nous aperçevons que cette fonctionnalité n'est pas disponible sur la version de MySQL utilisée, ou bien que le bug a été corrigé dans les versions plus récentes. Parfois, l'erreur dépend de l'OS. Dans ces cas, il est presque impossible de corriger l'erreur sans connaitre le nom de l'OS, et le numéro de version de la plate forme. N'oubliez pas d'inclure des inforamtions sur les compilateurs, si cela a un rapport avec votre problème. Souvent, on trouve des erreurs dans les compilateurs, et les utilisateurs pensent que c'est lié à MySQL. La plus part des compilateurs sont en développement constants, et s'améliorent de version en version. Pour savoir si votre problème dépend du compilateur, nous avons besoin de savoir quel compilateur est utilisé. Notez que chaque problème lié à la compilation doit être considéré comme un bug, et rapporté de manière adéquate. Une bonne description du problème est toujours utile dans un rapport de bug. C'est à dire, toutes les manipulations que vous avez faites, qui ont conduit au bug, et la description du bug lui même. Les meilleurs rapports inclus aussi un exemple complet pour reproduire le bug. Si un programme produit un message d'erreur, il est très important d'inclure le message dans votre rapport! Si vous recherchez dans les archives, il est préférable d'utiliser le message d'erreur exact (même la casse est importante). N'essayez pas de vous souvenir du message : faites en un copier/coller du message entier! Pensez à inclure les informations suivantes dans votre rapport:
Si vous être un client du support, n'envoyez pas le rapport en double sur l'adresse pour voir si quelqu'un expérimenté peut résoudre votre problème. Pour savoir comment rapporter à propos de MyODBC, allez à 16.2 Comment rapporter des bugs avec MyODBC. Pour des solutions aux problèmes courants, reportez vous à 18 Problèmes et erreurs fréquents. Lorsque des informations vous sont envoyées individuellement, et pas à la liste de diffusion, il est de bon ton de rassembler toutes les réponses, et de les envoyer à la liste de diffusion pour que le bénéfices des réponses profite à tous. 2.4 Règles pour répondre aux questions sur la liste de diffusionSi vous pensez que vous avec une réponse d'interêt général, vous voudrez surement envoyer un mail sur la liste de diffusion, plutôt que de répondre uniquement à la personne qui a posé la question. Essayez de rendre votre réponse aussi générale que possible, pour que tous ceux qui ne connaissent pas le problème initiale puisse comprendre. Lorsque vous envoyez votre réponse, vérifiez que vous n'etes pas en double avec une autre réponse. Dans votre réponse, essayez de résumer la question; ne vous sentez pas obligé de citer toute la question. N'envoyez pas de mail avec votre navigateur HTML. De nombreux utilisateurs ne lisent pas leur mail avec un navigateur. 3 Support et licences MySQLThis chapter describes MySQL licensing and support arrangements, including:
3.1 Politique de licence MySQLThe formal terms of the license for non-Microsoft operating systems such as Unix or OS/2 are specified in J Licence MySQL pour les sytèmes d'exploitation non-Microsoft. Basically, our licensing policy is as follows:
For use under Microsoft operating systems (Win95/Win98/WinNT), you need a MySQL license after a trial period of 30 days, with the exception that licenses may be obtained upon request at no cost for educational use or for university- or government-sponsored research settings. K Licence MySQL pour les OS Microsoft. A shareware version of MySQL-Win32 that you can try before buying is available at http://www.mysql.com/mysql_w32.htmy. After you have paid, you will get a password that will enable you to access the newest MySQL-Win32 version. If you have any questions as to whether or not a license is required for your particular use of MySQL, please contact us. 3.5.2 Contacts. If you require a MySQL license, the easiest way to pay for it is to use the license form at TcX's secure server at https://www.mysql.com/license.htmy. Other forms of payment are discussed in 3.5.1 Informations pratique de paiement. 3.2 Copyrights de MySQLThere are several different copyrights on the MySQL distribution:
The following points set forth the philosophy behind our copyright policy:
3.2.1 Modifications ultérieures possibles du copyrightWe may choose to distribute older versions of MySQL with the GPL in the future. However, these versions will be identified as GNU MySQL. Also, all copyright notices in the relevant files will be changed to the GPL. 3.3 Distribution commerciale de MySQLThis section is a clarification of the license terms that are set forth in the ``MySQL FREE PUBLIC LICENSE'' (FPL). J Licence MySQL pour les sytèmes d'exploitation non-Microsoft. MySQL may be used freely, including by commercial entities for evaluation or unsupported internal use. However, distribution for commercial purposes of MySQL, or anything containing or derived from MySQL in whole or in part, requires a written commercial license from TcX AB, the sole entity authorized to grant such licenses. You may not include MySQL ``free'' in a package containing anything for which a charge is being made, except as noted below. The intent of the exception provided in the second clause of the license is to allow commercial organizations operating an FTP server or a bulletin board to distribute MySQL freely from it, provided that:
If you want to distribute software in a commercial context that incorporates MySQL and you do not want to meet these conditions, you should contact TcX AB to find out about commercial licensing, which involves a payment. The only ways you legally can distribute MySQL or anything containing MySQL are by distributing MySQL under the requirements of the FPL, or by getting a commercial license from TcX AB. 3.4 Exemple de licencesThis section describes some situations illustrating whether or not you must license the MySQL server. Generally these examples involve providing MySQL as part of a product or service that you are selling to a customer, or requiring that MySQL be used in conjunction with your product. In such cases, it is your responsibility to obtain a license for the customer if one is necessary. (This requirement is waived if your customer already has a MySQL license. But the seller must send customer information and the license number to TcX, and the license must be a full license, not an OEM license.)
Note that a single MySQL license covers any number of
CPUs/users/customers/ 3.4.1 Vente de produits qui utilisent MySQLTo determine whether or not you need a MySQL license when selling your application, you should ask whether the proper functioning of your application is contingent on the use of MySQL and whether you include MySQL with your product. There are several cases to consider:
3.4.2 Vente de services MySQLIf you perform MySQL installation on a client's machine and any money changes hands for the service (directly or indirectly), then you must buy a MySQL license. If you sell an application for which MySQL is not strictly required but can be used, a license may be indicated, depending on how MySQL is set up. Suppose your product neither requires MySQL nor includes it in your product distribution, but can be configured to use MySQL for those customers who so desire. (This would be the case, for example, if your product can use any of a number of database engines.) If the customer obtains and installs MySQL, no license is needed. If you perform that service for your customer, then a license is needed because then you are selling a service that includes MySQL. 3.4.3 ISP MySQLInternet Service Providers (ISPs) often host MySQL servers for their customers. If you are an ISP that allows customers to install and administer MySQL for themselves on your machine with no assistance from you, neither you nor your customer need a MySQL license. If you charge for MySQL installation and administrative support as part of your customer service, then you need a license because you are selling a service that includes MySQL. 3.4.4 Utiliser un serveur web avec MySQLIf you use MySQL in conjunction with a web server, you don't have to pay for a license. This is true even if you run a commercial web server that uses MySQL, since you are not selling MySQL itself. However, in this case we would like you to purchase MySQL support, because MySQL is helping your enterprise. 3.5 Licences et couts du support MySQLOur current license prices are shown below. All prices are in US Dollars. If you pay by credit card, the currency is EURO (European Union Euro) so the prices will differ slightly.
For high volume (OEM) purchases, the following prices apply:
For OEM purchases, you must act as the middle-man for eventual problems or extension requests from your users. We also require that OEM customers have at least an extended email support contract. If you have a low-margin high-volume product, you can always talk to us about other terms (for example, a percent of the sale price). If you do, please be informative about your product, pricing, market and any other information that may be relevant.
After buying 10 MySQL licenses, you will get a personal copy of
the A full-price license is not a support agreement and includes very minimal support. This means that we try to answer any relevant question. If the answer is in the documentation, we will direct you to the appropriate section. If you have not purchased a license or support, we probably will not answer at all. If you discover what we consider a real bug, we are likely to fix it in any case. But if you pay for support we will notify you about the fix status instead of just fixing it in a later release. More comprehensive support is sold separately. Descriptions of what each level of support includes are given in 3.6 Types de support commercial. Costs for the various types of commercial support are shown below. Support level prices are in EURO (European Union Euro). One EURO is about 1.17 USD.
You may upgrade from any lower level of support to a higher level of support for the difference between the prices of the two support levels. 3.5.1 Informations pratique de paiementCurrently we can take SWIFT payments, cheques or credit cards. Payment should be made to: Postgirot Bank AB 105 06 STOCKHOLM, SWEDEN TCX DataKonsult AB BOX 6434 11382 STOCKHOLM, SWEDEN SWIFT address: PGSI SESS Account number: 96 77 06 - 3 Specify: license and/or support and your name and email address. In Europe and Japan you can use EuroGiro (that should be less expensive) to the same account. If you want to pay by cheque, make it payable to ``Monty Program KB'' and mail it to the address below: TCX DataKonsult AB BOX 6434 11382 STOCKHOLM, SWEDEN If you want to pay by credit card over the Internet, you can use TcX's secure license form. You can also print a copy of the license form, fill it in and send it by fax to: +46-8-729 69 05 If you want us to bill you, you can use the license form and write ``bill us'' in the comment field. You can also mail a message to with your company information and ask us to bill you. 3.5.2 ContactsFor commercial licensing, or if you have any questions about any of the information in this section, please contact the MySQL licensing team. The much preferred méthode is by E-Mail to these may take much longer (Fax +46-8-729 69 05). David Axmark Detron HB Kungsgatan 65 B 753 21 UPPSALA SWEDEN Voice Phone +46-18-10 22 80 (Timezone GMT+1. Swedish and English spoken) 3.6 Types de support commercial3.6.1 Support email basiqueBasic email support is a very inexpensive support option and should be thought of more as a way to support our development of MySQL than as a real support option. At this support level, the MySQL mailing lists are the preferred means of communication. Questions normally should be mailed to the primary mailing list (mysql@lists.mysql.com) or one of the other regular lists (for example, mysql-win32@lists.mysql.com for Windows-related MySQL questions), as someone else already may have experienced and solved the problem you have. 2.2 Poser des questions et rapporter des bugs. However, by purchasing basic email support, you also have access to the support address mysql-support@mysql.com, which is not available as part of the minimal support that you get by purchasing a MySQL license. This means that for especially critical questions, you can cross-post your message to mysql-support@mysql.com. (If the message contains sensitive data, you should post only to mysql-support@mysql.com.) REMEMBER! to ALWAYS include your registration number and expiration date when you send a message to Basic email support includes the following types of service:
3.6.2 Support email étenduExtended email support includes everything in basic email support with these additions:
3.6.3 Support de loginLogin support includes everything in extended email support with these additions:
3.6.4 Support de login étenduExtended login support includes everything in login support with these additions:
4 Instalation de MySQLThis chapter describes how to obtain and install MySQL:
4.1 Comment obtenir MySQLCheck the MySQL home page for information about the current version and for downloading instructions. However, the Internet connection at TcX is not so fast; we would prefer that you do the actual downloading from one of the mirror sites listed below. Please report bad or out of date mirrors to webmaster@mysql.com. Europe:
North America:
South America:
Asia:
Australia:
Africa: 4.2 Systèmes d'exploitation supportés par MySQLWe use GNU Autoconf so it is possible to port MySQL to all modern systems with working Posix threads and a C++ compiler. (To compile only the client code, a C++ compiler is required but not threads.) We use and develop the software ourselves primarily on Sun Solaris (versions 2.5 & 2.6) and to a lesser extent on RedHat Linux 5.0. MySQL has been reported to compile sucessfully on the following operating system/thread package combinations. Note that for many operating systems, the native thread support works only in the latest versions.
4.3 Quelle version de MySQL utiliserThe first decision to make is whether you want to use the latest development release or the last stable release:
The second decision to make is whether you want to use a source distribution or a binary distribution:
The MySQL naming scheme uses release numbers that consist of three
numbers and a suffix. For example, a release name like
All versions of MySQL are run through our standard tests and benchmarks to ensure that they are relatively safe to use. Since the standard tests are extended over time to check for all previously found bugs, the test suite keeps getting better. Note that all releases have been tested at least with:
Another test is that we use the newest MySQL version in our internal production environment, on at least one machine. We have more than 100 gigabytes of data to work with. 4.4 Comment et quand sont générées les mises à jourMySQL is evolving quite rapidly here at TcX and we want to share this with other MySQL users. We try to make a release when we have very useful features that others seem to have a need for. We also try to help out users who request features that are easy to implement. We also take note of what our licensed users want to have and we especially take note of what our extended email supported customers want and try to help them out. No one has to download a new release. The News section will tell you if the new release has something you really want. D Historique des versions de MySQL. We use the following policy when updating MySQL:
The current stable release is 3.22; We have already moved active development to 3.23. Bugs will still be fixed in the stable version. We don't believe in a complete freeze, as this also leaves out bug fixes and things that ``must be done''. ``Somewhat frozen'' means that we may add small things that ``almost surely will not affect anything that's already working''. 4.5 Structure de l'installationThis section describes the default layout of the directories created by installing binary and source distributions. A binary distribution is installed by unpacking it at the installation location you choose (typically `/usr/local/mysql') and creates the following directories in that location:
A source distribution is installed after you configure and compile it. By default, the installation step installs files under `/usr/local', in the following subdirectories:
Within an installation directory, the layout of a source installation differs from that of a binary installation in the following ways:
4.6 Installer une version binaire de MySQLYou need the following tools to install a MySQL binary distribution:
An alternative installation méthode under Linux is to use RPM (RedHat Package Manager) distributions. 4.6.1 Linux RPM.
If you run into problems, PLEASE ALWAYS USE The basic commands you must execute to install and use a MySQL binary distribution are: shell> gunzip < mysql-VERSION-OS.tar.gz | tar xvf - shell> ln -s mysql-VERSION-OS mysql shell> cd mysql shell> scripts/mysql_install_db shell> bin/safe_mysqld &
You can add new users using the Here follows a more detailed description: To install a binary distribution, follow the steps below, then proceed to 4.15 Paramètrage post-installation et tests, for post-installation setup and testing:
After everything has been unpacked and installed, you should initialize and test your distribution. You can start the MySQL server with the following command: shell> bin/safe_mysqld &
Note that MySQL versions older than 3.22.10 started the
MySQL server when you run 4.15 Paramètrage post-installation et tests. 4.6.1 Linux RPM
The recommended way to install MySQL on Linux is by using an RPM
file. The MySQL RPMs are currently being built on a RedHat 5.2
system but should work on other versions of Linux that support
If you have problems with an RPM file, for example The RPM files you may want to use are:
To see all files in an RPM package: shell> rpm -qpl MySQL-VERSION.i386.rpm To perform a standard minimal installation, run this command: shell> rpm -i MySQL-VERSION.i386.rpm MySQL-client-VERSION.i386.rpm To install just the client package: shell> rpm -i MySQL-client-VERSION.i386.rpm The RPM places data in `/var/lib/mysql'. The RPM also creates the appropriate entries in `/sbin/rc.d/' to start the server automatically at boot time. (This means that if you have performed a previous installation, you may want to make a copy of your previously-installed MySQL startup file if you made any changes to it, so you don't lose your changes.) After installing the RPM file(s), go to the binary install section and use the instructions there, starting from the step that creates the MySQL grant tables. 4.6 Installer une version binaire de MySQL. 4.6.2 Construire un programme client
If you compile MySQL clients that you've written yourself or that
you obtain from a third party, they must be linked using the
For clients that use MySQL header files, you may need to specify a
4.6.3 Instruction spécifiques aux OSThe following sections indicate some of the issues that have been observed to occur on particular systems when installing MySQL from a binary distribution. 4.6.3.1 Linux notesMySQL needs at least Linux 2.0.
The binary release is linked with
If you are using a Sorry, the host 'xxxx' could not be looked up
or the following error when you try to run mysqld with the getpwnam: No such file or directory You can solve this problem one of the following ways:
The Linux-Intel binary and RPM releases of MySQL are configured for the highest possible speed. We are always trying to use the fastest stable compiler available. MySQL Perl support requires Perl 5.004_03 or newer. 4.6.3.2 HP-UX notesThe binary distribution of MySQL for HP-UX is distributed as an HP depot file and as a tar file. To use the depot file you must be running at least HP-UX 10.x to have access to HP's software depot tools. The HP version of MySQL was compiled on an HP 9000/8xx server under HP-UX 10.20, and uses MIT-pthreads. It is known to work well under this configuration. MySQL 3.22.26 and newer can also be built with HP's native thread package. Other configurations that may work:
The following configurations almost definitely won't work:
To install the distribution, use one of the commands below, where
The depot places binaries and libraries in `/opt/mysql' and data in
`/var/opt/mysql'. The depot also creates the appropriate entries in
`/sbin/init.d' and `/sbin/rc2.d' to start the server automatically
at boot time. Obviously, this entails being To install the HP-UX tar distribution, you must have a copy of gnu tar. 4.7 Installer une version source de MySQLYou need the following tools to build and install MySQL from source:
If you run into problems, PLEASE ALWAYS USE 4.7.1 Introduction à l'installation rapide
The basic commands you must execute to install a MySQL source
distribution are (from an unpacked shell> configure shell> make shell> make install shell> scripts/mysql_install_db shell> /usr/local/mysql/bin/safe_mysqld & If you start from a source RPM, then do the following. shell> rpm --rebuild MySQL-VERSION.src.rpm This will make a binary RPM that you can install.
You can add new users using the Here follows a more detailed description: To install a source distribution, follow the steps below, then proceed to 4.15 Paramètrage post-installation et tests, for post-installation initialization and testing.
After everything has been installed, you should initialize and test your distribution.
You can start the MySQL server with the following command,
where shell> BINDIR/safe_mysqld &
If that command fails immediately with 4.15 Paramètrage post-installation et tests. 4.7.2 Appliquer un patchSometimes patches appear on the mailing list or are placed in the patches area of the MySQL FTP site. To apply a patch from the mailing list, save the message in which the patch appears in a file, change into the top-level directory of your MySQL source tree and run these commands: shell> patch -p1 < patch-file-name shell> rm config.cache shell> make clean
Patches from the FTP site are distributed as plain text files or as files
compressed with shell> gunzip < patch-file-name.gz | patch -p1 shell> rm config.cache shell> make clean
After applying a patch, follow the instructions for a normal source install,
beginning with the
You may need to bring down any currently running server before you run
4.7.3 Options communes de
|
mysqld | Compiled with full debugging and automatic memory allocation checking |
mysqld-opt | Optimized for a Pentium processor. |
Both of the above should work on any Intel processor >= i386.
To start the mysqld
server, you should start a MS-DOS window and type:
C:\mysql\bin\mysqld
This will start mysqld
in the background without a window.
You can kill the MySQL server by executing:
C:\mysql\bin\mysqladmin -u root shutdown
Note that Win95/Win98 don't support creation of named pipes. On Win95/Win98, you can only use named pipes to connect to a remote MySQL running on an NT server.
The Win95/Win98 section also applies to MySQL on NT, with the following differences:
To get MySQL to work with TCP/IP, you must install service pack 3 (or newer)!
For NT, the server name is mysqld-nt
. Normally you should install
MySQL as a service on NT:
C:\mysql\bin\mysqld-nt --install
(You could use the mysqld
or mysqld-opt
servers on NT,
but those cannot be started as a service or use named pipes.)
You can start and stop the MySQL service with:
NET START mysql NET STOP mysql
Note that in this case you can't use any other options for mysqld-nt
!
You can also run mysqld-nt
as a standalone program on NT if you need
to start mysqld-nt
with any options! If you start mysqld-nt
without options on NT, mysqld-nt
tries to starts itself as a service
with the default service options. If you have stopped mysqld-nt
, you
have to start it with NET START mysql
.
The service is installed with the name MySql
. Once installed, it must
be started using Services Control Manager (SCM) Utility (found in Control
Panel) or by using the NET START MySQL
command. If any options are
desired, they must be specified as "Startup parameters" in the SCM utility
before you start the MySQL service. Once running, mysqld-nt
can be stopped using mysqladmin
or from the SCM utility or by using
the command NET STOP MySQL
. If you use SCM to stop mysqld-nt
,
there is a strange message from SCM about mysqld shutdown normally
.
When run as a service, mysqld-nt
has no access to a console and so no
messages can be seen.
On NT you can get the following service error messages:
Permission Denied | Means that it cannot find mysqld-nt.exe
|
Cannot Register | Means that the path is incorrect |
If you have problems installing mysqld-nt
as a service, try starting
it with the full path:
C:\mysql\bin\mysqld --install
If this doesn't work, you can get mysqld-nt
to start properly by fixing
the path in the registry!
If you don't want to start mysqld-nt
as a service, you can start it as
follows:
C:\mysql\bin\mysqld-nt --standalone
or
C:\mysql\bin\mysqld-nt --standalone --debug
The last version gives you a debug trace in `C:\mysqld.trace'.
MySQL supports TCP/IP on all Win32 platforms and named pipes on NT. The default is to use named pipes for local connections on NT and TCP/IP for all other cases if the client has TCP/IP installed. The host name specifies which protocol is used:
Host nameprotocol | |
NULL (none) | On NT, try named pipes first; if that doesn't work, use TCP/IP. On Win95/Win98, TCP/IP is used. |
. | Named pipes |
localhost | TCP/IP to current host |
hostname | TCP/IP |
You can force a MySQL client to use named pipes by specifying the
--pipe
option. Use the --socket
option to specify the name of
the pipe.
You can test whether or not MySQL is working by executing the following commands:
C:\mysql\bin\mysqlshow C:\mysql\bin\mysqlshow -u root mysql C:\mysql\bin\mysqladmin version status proc C:\mysql\bin\mysql test
By default, MySQL-Win32 is configured to be installed in
`C:\mysql'. If you want to install MySQL elsewhere, install it
in `C:\mysql', then move the installation to where you want it. If you
do move MySQL, you must tell mysqld
where everything is by
supplying options to mysqld
. Use C:\mysql\bin\mysqld --help
to
display all options! If, for example, you have moved the MySQL
distribution to `D:\programs\mysql', you must start mysqld
with:
D:\programs\mysql\bin\mysqld --basedir D:\programs\mysql
With the registered version of MySQL, you can also create a
`C:\my.cnf' file that holds any default options for the
MySQL server. Copy the file `\mysql\my-example.cnf' to
`C:\my.cnf' and edit this to suit your setup. Note that you should
specify all paths with /
instead of \
. If you use
\
, you need to specify this twice, as \
is the escape
character in MySQL.
4.15.4 Fichier d'options.
If mysqld
is slow to answer to connections on Win95/Win98, there is
probably a problem with your DNS. In this case, start mysqld
with
--skip-name-resolve
and use only localhost
and IP numbers in
the MySQL grant tables. You can also avoid DNS when connecting to a
mysqld-nt
MySQL server running on NT by using the
--pipe
argument to specify use of named pipes. This works for most
MySQL clients.
There are two versions of the MySQL command line tool:
mysql | Compiled on native Win32, which offers very limited text editing capabilities. |
mysqlc | Compiled with the Cygnus GNU compiler and libraries, which offers readline editing.
|
If you want to use mysqlc.exe
, you must copy
`C:\mysql\lib\cygwinb19.dll' to `\windows\system' (or similar
place).
The default privileges on Win32 give all local users full privileges
to all databases. To make MySQL more secure, you
should set a password for all users and remove the row in the
mysql.user
table that has Host='localhost'
and
User=''
.
You should also add a password for the root
user:
C:\mysql\bin\mysql mysql mysql> DELETE FROM user WHERE Host='localhost' AND User=''; mysql> QUIT C:\mysql\bin\mysqladmin reload C:\mysql\bin\mysqladmin -u root password your_password
After you've set the password, if you want to take down the mysqld
server, you can do so using this command:
mysqladmin --user=root --password=your_password shutdown
Here is a note about how to connect to get a secure connection to remote MySQL server with SSH (by David Carlson).
local port: 3306
,
host: localhost
, remote port: 3306
That's it. It works very well with a direct Internet connection. I'm having problems with SSH conflicting with my Win95 network and Wingate - but that'll be the topic of a posting on another software company's usegroup!
MySQL-Win32 has by now proven itself to be very stable. This version of MySQL has the same features as the corresponding Unix version with the following exceptions:
mysqld
for an extended time on Win95 if
you do many connections, since each connection in MySQL creates
a new thread! WinNT and Win98 don't suffer from this bug.
mysqladmin kill
will not work on a sleeping connection.
mysqladmin shutdown
can't abort as long as there are sleeping
connections.
DROP DATABASE
mysqladmin shutdown
.
my_table
and as MY_TABLE
:
SELECT * FROM my_table WHERE MY_TABLE.col=1;
LOAD
DATA INFILE
or SELECT ... INTO OUTFILE
, you must double the `\'
character or use Unix style filenames `/' characters:
LOAD DATA INFILE "C:\\tmp\\skr.txt" INTO TABLE skr; SELECT * FROM skr INTO OUTFILE 'C:/tmp/skr.txt';
Can't open named pipe
error
error 2017: can't open named pipe to host: . pipe...This is because the release version of MySQL uses named pipes on NT by default. You can avoid this error by using the
--host=localhost
option to the new MySQL clients
or create a file `C:\my.cnf' that contains the following information:
[client] host = localhost
Access denied for user
error
Access denied for user: 'some-user@unknown'
to database 'mysql'
when accessing a MySQL server on the same
machine, this means that MySQL can't resolve your host name
properly.
To fix this, you should create a file `\windows\hosts' with the
following information:
127.0.0.1 localhost
Here are some open issues for anyone who might want to help us with the Win32 release:
MYSQL.DLL
server. This should include everything in
a standard MySQL server, except thread creation. This will make
MySQL much easier to use in applications that don't need a true
client/server and don't need to access the server from other hosts.
mysqld.cc
,
but it should be recoded to be more ``parameter'' oriented.
The tool should also be able to update the `\my.cnf' file if the user
would prefer to use this instead of the registry.
mysqld
as a service with --install
(on NT)
it would be nice if you could also add default options on the command line.
For the moment, the workaround is to update the `C:\my.cnf' file
instead.
mysqld
daemon doesn't accept new connections when the laptop is resumed.
We don't know if this is a problem with Win95, TCP/IP or MySQL.
mysqld
from the
task manager. For the moment, you must use mysqladmin shutdown
.
readline
to Win32 for use in the mysql
command line tool.
mysql
,
mysqlshow
, mysqladmin
, and mysqldump
) would be nice.
mysqladmin kill
on Win32.
mysqld
always starts in the "C" locale and not in the default locale.
We would like to have mysqld
use the current locale for the sort order.
sqlclient
to Win32 (almost done) and add more features to it!
.DLL
s.
Other Win32-specific issues are described in the `README' file that comes with the MySQL-Win32 distribution.
MySQL uses quite a few open files. Because of this, you should add something like the following to your `CONFIG.SYS' file:
SET EMXOPT=-c -n -h1024
If you don't do this, you will probably run into the following error:
File 'xxxx' not found (Errcode: 24)
When using MySQL with OS/2 Warp 3, FixPack 29 or above is required. With OS/2 Warp 4, FixPack 4 or above is required. This is a requirement of the Pthreads library. MySQL must be installed in a partition that supports long file names such as HPFS, FAT32, etc.
The `INSTALL.CMD' script must be run from OS/2's own `CMD.EXE' and may not work with replacement shells such as `4OS2.EXE'.
The `scripts/mysql-install-db' script has been renamed: it is now called `install.cmd' and is a REXX script which will set up the default MySQL security settings and create the WorkPlace Shell icons for MySQL.
Dynamic module support is compiled in but not fully tested. Dynamic modules should be compiled using the Pthreads runtime library.
gcc -Zdll -Zmt -Zcrtdll=pthrdrtl -I../include -I../regex -I.. \ -o example udf_example.cc -L../lib -lmysqlclient udf_example.def mv example.dll example.udf
Note: Due to limitations in OS/2, UDF module name stems must not
exceed 8 characters. Modules are stored in the `/mysql2/udf'
directory; the safe-mysqld.cmd
script will put this directory in
the BEGINLIBPATH
environment variable. When using UDF modules,
specified extensions are ignored -- it is assumed to be `.udf'.
For example, in Unix, the shared module might be named `example.so'
and you would load a function from it like this:
CREATE FUNCTION metaphon RETURNS STRING SONAME "example.so";
Is OS/2, the module would be named `example.udf', but you would not specify the module extension:
CREATE FUNCTION metaphon RETURNS STRING SONAME "example";
As a service, TcX provides a set of binary distributions of MySQL that are compiled at TcX or at sites where customers kindly have given us access to their machines.
These distributions
are generated with scripts/make_binary_distribution
and are
configured with the following compilers and options:
gcc
2.7.2.1
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --disable-shared
egcs
1.0.3a
CC=gcc CFLAGS="-O6 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O6 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-low-memory
egcs
2.90.27
CC=gcc CFLAGS="-O6 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O6 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-low-memory
gcc
2.8.1
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-low-memory
pgcc
2.90.29 (egcs
1.0.3a)
CFLAGS="-O6 -mpentium -mstack-align-double -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O6 -mpentium -mstack-align-double -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static
gcc
2.7-95q4
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
gcc
2.7.2.2
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
gcc
2.8.1
CC=gcc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-low-memory
gcc
2.8.0
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
gcc
2.7.2.1
CC=gcc CXX=gcc CXXFLAGS=-O ./configure --prefix=/usr/local/mysql
gcc
2.7.2
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
Anyone who has more optimal options for any of the configurations listed above can always mail them to the developer's mailing list at
RPM distributions prior to MySQL 3.22 are user-contributed. Beginning with 3.22, some RPMs are TcX-generated.
Once you've installed MySQL (from either a binary or source distribution), you need to initialize the grant tables, start the server and make sure that the server works okay. You may also wish to arrange for the server to be started and stopped automatically when your system starts up and shuts down.
Normally you install the grant tables and start the server like this:
shell> cd mysql_installation_directory shell> ./bin/mysql_install_db shell> ./bin/safe_mysqld &
Testing is most easily done from the top-level directory of the MySQL distribution. For a binary distribution, this is your installation directory (typically something like `/usr/local/mysql'). For a source distribution, this is the main directory of your MySQL source tree.
In the commands shown below in this section and in the following
subsections, BINDIR
is the path to the location in which programs
like mysqladmin
and safe_mysqld
are installed. For a
binary distribution, this is the `bin' directory within the
distribution. For a source distribution, BINDIR
is probably
`/usr/local/bin', unless you specified an installation directory
other than `/usr/local' when you ran configure
.
EXECDIR
is the location in which the mysqld
server is
installed. For a binary distribution, this is the same as
BINDIR
. For a source distribution, EXECDIR
is probably
`/usr/local/libexec'.
Testing is described in detail below:
mysqld
server and set up the initial
MySQL grant tables containing the privileges that determine how
users are allowed to connect to the server. This is normally done with the
mysql_install_db
script:
shell> scripts/mysql_install_dbTypically,
mysql_install_db
needs to be run only the first time you
install MySQL. Therefore, if you are upgrading an existing
installation, you can skip this step. (However, mysql_install_db
is
quite safe to use and will not update any tables that already exist, so if
you are unsure what to do, you can always run mysql_install_db
.)
mysql_install_db
creates six tables (user
, db
,
host
, tables_priv
, columns_priv
and func
) in the
mysql
database. A description of the initial privileges is given in
6.10 Droits initiaux. Briefly, these privileges allow the MySQL
root
user to do anything, and allow anybody to create or use databases
with a name of 'test'
or starting with 'test_'
.
If you don't set up the grant tables, the following error will appear in the
log file when you start the server:
mysqld: Can't find file: 'host.frm'The above may also happens with a binary MySQL distribution if you don't start MySQL by executing exactly
./bin/safe_mysqld
!
You might need to run mysql_install_db
as root
. However,
if you prefer, you can run the MySQL server as an unprivileged
(non-root
) user, provided that user can read and write files in
the database directory. Instructions for running MySQL as an
unprivileged user are given in Changing MySQL user.
If you have problems with mysql_install_db
, see
mysql_install_db
.
There are some alternatives to running the mysql_install_db
script as it is provided in the MySQL distribution:
mysql_install_db
before running it, to
change the initial privileges that are installed into the grant tables.
This is useful if you want to install MySQL on a lot of machines
with the same privileges. In this case you probably should need only to add
a few extra INSERT
statements to the mysql.user
and
mysql.db
tables!
mysql_install_db
, then use mysql -u root mysql
to
connect to the grant tables as the MySQL root
user and issue
SQL statements to modify the grant tables directly.
mysql_install_db
.
shell> cd mysql_installation_directory shell> bin/safe_mysqld &If you have problems starting the server, see 4.15.2 Problèmes avec le serveur MySQL.
mysqladmin
to verify that the server is running. The following
commands provide a simple test to check that the server is up and responding
to connections:
shell> BINDIR/mysqladmin version shell> BINDIR/mysqladmin variablesThe output from
mysqladmin version
varies slightly depending on your
platform and version of MySQL, but should be similar to that shown
below:
shell> BINDIR/mysqladmin version mysqladmin Ver 6.3 Distrib 3.22.9-beta, for pc-linux-gnu on i686 TCX Datakonsult AB, by Monty Server version 3.22.9-beta Protocol version 10 Connection Localhost via UNIX socket TCP port 3306 UNIX socket /tmp/mysql.sock Uptime: 16 sec Running threads: 1 Questions: 20 Reloads: 2 Open tables: 3To get a feeling for what else you can do with
BINDIR/mysqladmin
,
invoke it with the --help
option.
shell> BINDIR/mysqladmin -u root shutdown
safe_mysqld
or
by invoking mysqld
directly. For example:
shell> BINDIR/safe_mysqld --log &If
safe_mysqld
fails, try running it from the MySQL
installation directory (if you are not already there). If that doesn't work,
see 4.15.2 Problèmes avec le serveur MySQL.
shell> BINDIR/mysqlshow +-----------+ | Databases | +-----------+ | mysql | +-----------+ shell> BINDIR/mysqlshow mysql Database: mysql +--------------+ | Tables | +--------------+ | columns_priv | | db | | func | | host | | tables_priv | | user | +--------------+ shell> BINDIR/mysql -e "select host,db,user from db" mysql +------+--------+------+ | host | db | user | +------+--------+------+ | % | test | | | % | test_% | | +------+--------+------+There is also a benchmark suite in the `sql-bench' directory (under the MySQL installation directory) that you can use to compare how MySQL performs on different platforms. The `sql-bench/Results' directory contains the results from many runs against different databases and platforms. To run all tests, execute these commands:
shell> cd sql-bench shell> run-all-testsIf you don't have the `sql-bench' directory, you are probably using an RPM for a binary distribution. (Source distribution RPMs include the benchmark directory.) In this case, you must first install the benchmark suite before you can use it. Beginning with MySQL 3.22, there are benchmark RPM files named `mysql-bench-VERSION-i386.rpm' that contain benchmark code and data. If you have a source distribution, you can also run the tests in the `tests' subdirectory. For example, to run `auto_increment.tst', do this:
shell> BINDIR/mysql -vvf test < ./tests/auto_increment.tstThe expected results are shown in the `./tests/auto_increment.res' file.
mysql_install_db
This section lists problems you might encounter when you run
mysql_install_db
:
mysql_install_db
doesn't install the grant tables
mysql_install_db
fails to install the grant
tables and terminates after displaying the following messages:
starting mysqld daemon with databases from XXXXXX mysql daemon endedIn this case, you should examine the log file very carefully! The log should be located in the directory `XXXXXX' named by the error message, and should indicate why
mysqld
didn't start. If you don't understand
what happened, include the log when you post a bug report using
mysqlbug
!
2.3 Comment rapporter des bugs et des problèmes.
mysqld
daemon running
mysql_install_db
at
all. You have to run mysql_install_db
only once, when you install
MySQL the first time.
mysqld
daemon doesn't work when one daemon is running
Can't start server: Bind on
TCP/IP port: Address already in use
or Can't start server : Bind on
unix socket...
You can start the new server with a different socket and
port as follows:
shell> MYSQL_UNIX_PORT=/tmp/mysqld-new.sock shell> MYSQL_TCP_PORT=3307 shell> export MYSQL_UNIX_PORT MYSQL_TCP_PORT shell> scripts/mysql_install_db shell> bin/safe_mysqld &After this, you should edit your server boot script to start both daemons with different sockets and ports. For example, it could invoke
safe_mysqld
twice, but with different --socket
, --port
and --basedir
options for each invocation.
mysql_install_db
or when
starting or using mysqld
.
You can specify a different socket and temporary directory as follows:
shell> TMPDIR=/some_tmp_dir/ shell> MYSQL_UNIX_PORT=/some_tmp_dir/mysqld.sock shell> export TMPDIR MYSQL_UNIX_PORT`some_tmp_dir' should be the path to some directory for which you have write permission. After this you should be able to run
mysql_install_db
and start
the server with these commands:
shell> scripts/mysql_install_db shell> BINDIR/safe_mysqld &
mysqld
crashes immediately
glibc
older than
2.0.7-5, you should make sure you have installed all glibc
patches!
There is a lot of information about this in the MySQL mail
archives. Links to the mail archives are available at the online
MySQL documentation page.
Also, see 4.11.5 Linux (Toutes versions de Linux).
You can also start mysqld
manually using the --skip-grant
option and add the privilege information yourself using mysql
:
shell> BINDIR/safe_mysqld --skip-grant & shell> BINDIR/mysql -u root mysqlFrom
mysql
, manually execute the SQL commands in mysql_install_db
.
Make sure you run mysqladmin reload
afterward to tell the
server to reload the grant tables.
Generally, you start the mysqld
server in one of three ways:
mysql.server
. This script is used primarily at
system startup and shutdown, and is described more fully in
4.15.3 Démarrer et arrête MySQL automatiquement.
safe_mysqld
, which tries to determine the proper options
for mysqld
and then runs it with those options.
mysqld
directly.
Whichever méthode you use to start the server, if it fails to start up
correctly, check the log file to see if you can find out why. Log files
are located in the data directory (typically
`/usr/local/mysql/data' for a binary distribution,
`/usr/local/var' for a source distribution). Look in the data
directory for files with names of the form `host_name.err' and
`host_name.log' where host_name
is the name of your server
host. Then check the last few lines of these files:
shell> tail host_name.err shell> tail host_name.log
When the mysqld
daemon starts up, it changes directory to the
data directory. This is where it expects to write log files and the pid
(process ID) file, and where it expects to find databases.
The data directory location is hardwired in when the distribution is
compiled. However, if mysqld
expects to find the data directory
somewhere other than where it really is on your system, it will not work
properly. If you have problems with incorrect paths, you can find out
what options mysqld
allows and what the default path settings are by
invoking mysqld
with the --help
option. You can override the
defaults by specifying the correct pathnames as command-line arguments to
mysqld
. (These options can be used with safe_mysqld
as well.)
Normally you should need to tell mysqld
only the base directory under
which MySQL is installed. You can do this with the --basedir
option. You can also use --help
to check the effect of changing path
options (note that --help
must be the final option of the
mysqld
command). For example:
shell> EXECDIR/mysqld --basedir=/usr/local --help
Once you determine the path settings you want, start the server without
the --help
option.
If you get the following error, it means that some other program (or another
mysqld
server) is already using the TCP/IP port or socket
mysqld
is trying to use:
Can't start server: Bind on TCP/IP port: Address already in use or Can't start server : Bind on unix socket...
Use ps
to make sure that you don't have another mysqld
server
running. If you can't find another server running, you can try to execute
the command telnet your-host-name tcp-ip-port-number
and press
RETURN
a couple of times. If you don't get a error message like
telnet: Unable to connect to remote host: Connection refused
,
something is using the TCP/IP port mysqld
is trying to use.
mysql_install_db
, and 19.3 Faire tourner plusieurs serveurs MySQL sur la même machine.
The safe_mysqld
script is written so that it normally is able to start
a server that was installed from either a source or a binary version of
MySQL, even if these install the server in slightly different
locations. safe_mysqld
expects one of these conditions to be true:
safe_mysqld
is invoked. safe_mysqld
looks under its working
directory for `bin' and `data' directories (for binary
distributions) or for `libexec' and `var' directories (for source
distributions). This condition should be met if you execute
safe_mysqld
from your MySQL installation directory (for
example, `/usr/local/mysql' for a binary distribution).
safe_mysqld
attempts to locate them by absolute pathnames. Typical
locations are `/usr/local/libexec' and `/usr/local/var'.
The actual locations are determined when the distribution was built from which
safe_mysqld
comes. They should be correct if
MySQL was installed in a standard location.
Since safe_mysqld
will try to find the server and databases relative
to its own working directory, you can install a binary distribution of
MySQL anywhere, as long as you start safe_mysqld
from the
MySQL installation directory:
shell> cd mysql_installation_directory shell> bin/safe_mysqld &
If safe_mysqld
fails, even when invoked from the MySQL
installation directory, you can modify it to use the path to mysqld
and the pathname options that are correct for your system. Note that if you
upgrade MySQL in the future, your modified version of
safe_mysqld
will be overwritten, so you should make a copy of your
edited version that you can reinstall.
If mysqld
is currently running, you can find out what path settings
it is using by executing this command:
shell> mysqladmin variables or shell> mysqladmin -h 'your-host-name' variables
If safe_mysqld
starts the server but you can't connect to it,
you should make sure you have an entry in `/etc/hosts' that looks like
this:
127.0.0.1 localhost
This problem occurs only on systems that don't have a working thread library and for which MySQL must be configured to use MIT-pthreads.
The mysql.server
script can be used to start or stop the server,
by invoking it with start
or stop
arguments:
shell> mysql.server start shell> mysql.server stop
mysql.server
can be found in the `share/mysql' directory
under the MySQL installation directory, or in the `support-files'
directory of the MySQL source tree.
Before mysql.server
starts the server, it changes directory to
the MySQL installation directory, then invokes
safe_mysqld
. You might need to edit mysql.server
if you
have a binary distribution that you've installed in a non-standard
location. Modify it to cd
into the proper directory before it
runs safe_mysqld
. If you want the server to run as some specific
user, you can change the mysql_daemon_user=root
line to use
another user. You can also modify mysql.server
to pass other
options to safe_mysqld
.
mysql.server stop
brings down server by sending a signal to it.
You can take down the server manually by executing mysqladmin shutdown
.
You might want to add these start and stop commands to the appropriate places
in your `/etc/rc*' files when you start using MySQL for
production applications. Note that if you modify mysql.server
, then
if you upgrade MySQL sometime, your modified version will be
overwritten, so you should make a copy of your edited version that you can
reinstall.
If your system uses `/etc/rc.local' to start external scripts, you should append the following to it:
/bin/sh -c 'cd /usr/local/mysql ; ./bin/safe_mysqld &'
You can also add options or mysql.server
in a global
`/etc/my.cnf' file. A typical `/etc/my.cnf' file might look like
this:
[mysqld] datadir=/usr/local/mysql/var socket=/tmp/mysqld.sock port=3306 [mysql.server] user=mysql basedir=/usr/local/mysql
The mysql.server
script uses the following variables:
user
, datadir
, basedir
, bindir
and pid-file
.
MySQL 3.22 can read default startup options for the server and for clients from option files.
MySQL reads default options from the following files on Unix:
Filename | Purpose |
/etc/my.cnf | Global options |
DATADIR/my.cnf | Server-specific options |
~/.my.cnf | User-specific options |
DATADIR
is the MySQL data directory (typically
`/usr/local/mysql/data' for a binary installation, or
`/usr/local/var' for a source installation). Note that this is the
directory that was specified at configuration time, not the one specified
with --datadir
when mysqld
starts up! (--datadir
has no
effect on where the server looks for option files, because it looks for them
before it processes any command-line arguments.)
MySQL reads default options from the following files on Win32:
Filename | Purpose |
windows-system-directory\my.ini
| |
C:\my.cnf | Global options |
C:\mysql\data\my.cnf | Server-specific options |
Note that you on Win32 should specify all paths with /
instead of
\
. If you use \
, you need to specify this twice, as
\
is the escape character in MySQL.
MySQL tries to read option files in the order listed above. If multiple option files exist, an option specified in a file read later takes precedence over the same option specified in a file read earlier. Options specified on the command line take precedence over options specified in any option file. Some options can be specified using environment variables. Options specified on the command line or in option files take precedence over environment variable values.
The following programs support option files: mysql
,
mysqladmin
, mysqld
, mysqldump
, mysqlimport
,
mysql.server
, isamchk
and pack_isam
.
You can use option files to specify any long option that a program supports!
Run the program with --help
to get a list of available options.
An option file can contain lines of the following forms:
#comment
[group]
group
is the name of the program or group for which you want to set
options. After a group line, any option
or set-variable
lines
apply to the named group until the end of the option file or another group
line is given.
option
--option
on the command line.
option=value
--option=value
on the command line.
set-variable = variable=value
--set-variable variable=value
on the command line.
This syntax must be used to set a mysqld
variable.
The client
group allows you to specify options that apply to all
MySQL clients (not mysqld
). This is the perfect group to use
to specify the password you use to connect to the server. (But make
sure the option file is readable and writable only to yourself.)
Note that for options and values, all leading and trailing blanks are automatically deleted. You may use the escape sequences `\b', `\t', `\n', `\r', `\\' and `\s' in your value string (`\s' == blank).
Here is a typical global option file:
[client] port=3306 socket=/tmp/mysql.sock [mysqld] port=3306 socket=/tmp/mysql.sock set-variable = key_buffer=16M set-variable = max_allowed_packet=1M [mysqldump] quick
Here is typical user option file:
[client] # The following password will be sent to all standard MySQL clients password=my_password [mysql] no-auto-rehash
If you have a source distribution, you will find a sample configuration file
named `my-example.cnf' in the `support-files' directory. If you
have a binary distribution, look in the `DIR/share/mysql' directory,
where DIR
is the pathname to the MySQL installation directory
(typically `/usr/local/mysql'). You can copy `my-example.cnf' to
your home directory (rename the copy to `.my.cnf') to experiment with.
To tell a MySQL program not to read any option files, specify
--no-defaults
as the first option on the command line. This
MUST be the first option or it will have no effect!
If you want to check which options are used, you can give the option
--print-defaults
as the first option.
If you want to force the use of a specific config file, you can use the option
--defaults-file=full-path-to-default-file
. If you do this, only the
specified file will be read.
Note for developers: Option file handling is implemented simply by processing all matching options (i.e., options in the appropriate group) before any command line arguments. This works nicely for programs that use the last instance of an option that is specified multiple times. If you have an old program that handles multiply-specified options this way but doesn't read option files, you need add only two lines to give it that capability. Check the source code of any of the standard MySQL clients to see how to do this.
You can always move the MySQL form and data files between
different versions on the same architecture as long as you have the same
base version of MySQL. The current base version is
3. If you change the character set by recompiling MySQL (which may
also change the sort order), you must run isamchk -r -q
on all tables.
Otherwise your indexes may not be ordered correctly.
If you are paranoid and/or afraid of new versions, you can always rename your
old mysqld
to something like mysqld
-'old-version-number'. If
your new mysqld
then does something unexpected, you can simply shut it
down and restart with your old mysqld
!
When you do an upgrade you should also backup your old databases, of course. Sometimes it's good to be a little paranoid!
After an upgrade, if you experience problems with recompiled client programs,
like Commands out of sync
or unexpected core dumps, you probably have
used an old header or library file when compiling your programs. In this
case you should check the date for your `mysql.h' file and
`libmysqlclient.a' library to verify that they are from the new
MySQL distribution. If not, please recompile your programs!
If you get some problems that the new mysqld
server doesn't want to
start or that you can't connect without a password, check that you don't
have some old `my.cnf' file from your old installation! You can
check this with: program-name --print-defaults
. If this outputs
anything other than the program name, you have a active my.cnf
file that will may affect things!
It is a good idea to rebuild and reinstall the Msql-Mysql-modules
distribution whenever you install a new release of MySQL,
particularly if you notice symptoms such as all your DBI
scripts
dumping core after you upgrade MySQL.
MySQL 3.23 supports tables of the new MyISAM
type and
the old NISAM
type. You don't have to convert your old tables to
use these with 3.23. By default, all new tables will be created with
type MyISAM
(unless you start mysqld
with the
--default-table-type=isam
option. You can change an ISAM
table to a MyISAM
table with ALTER TABLE
or the Perl script
mysql_convert_table_format
.
3.22 and 3.21 clients will work without any problems with a 3.23 server.
The following lists what you have to watch out for when upgrading to 3.23:
INNER
and DELAYED
are now reserved words.
FLOAT(4)
and FLOAT(8)
are now true floating point types.
DECIMAL(length,dec)
the length argument no
longer includes a place for the sign or the decimal point.
TIME
string must now be of one of the following formats: [[[DAYS] [H]H:]MM:]SS[.fraction]
or [[[[[H]H]H]H]MM]SS[.fraction]
LIKE
now compares strings using the same character comparison rules as '='
.
If you require the old behavior, you can compile MySQL with
the CXXFLAGS=-DLIKE_CMP_TOUPPER
flag.
myisamchk
for MyISAM
tables (.MYI
) and isamchk
for ISAM (.ISM
) tables.
mysqldump
s to be compatible between MySQL 3.22 and 3.23,
you should not use the --opt
or --full
option to
mysqldump
.
DATE_FORMAT()
to make sure there is a `%'
before each format character.
mysql_fetch_fields_direct
is now a function (it was a macro) and
it returns a pointer to a MYSQL_FIELD
instead of a
MYSQL_FIELD
.
mysql_num_fields()
can no longer be used on a MYSQL*
object (it's
now a function that takes MYSQL_RES*
as an argument. You should now
use mysql_field_count()
instead.
MySQL
3.22, the output of SELECT DISTINCT ...
was
almost always sorted. In 3.23, you must use GROUP BY
or
ORDER BY
to obtain sorted output.
SUM()
now returns NULL
, instead of 0, if there is no matching
rows. This is according to ANSI SQL.
CASE, THEN, WHEN, ELSE and END
Nothing that affects compatibility has changed between 3.21 and 3.22. The
only pitfall is that new tables that are created with DATE
type
columns will use the new way to store the date. You can't access these new
fields from an old version of mysqld
.
After installing MySQL 3.22, you should start the new server and
then run the mysql_fix_privilege_tables
script. This will add the new
privileges that you need to use the GRANT
command. If you forget
this, you will get Access denied
when you try to use ALTER
TABLE
, CREATE INDEX
or DROP INDEX
. If your MySQL root
user requires a password, you should give this as an argument to
mysql_fix_privilege_tables
.
The C API interface to mysql_real_connect()
has changed. If you have
an old client program that calls this function, you must place a 0
for
the new db
argument (or recode the client to send the db
element for faster connections). You must also call mysql_init()
before calling mysql_real_connect()
! This change was done to allow
the new mysql_options()
function to save options in the MYSQL
handler structure.
If you are running a version older than 3.20.28 and want to switch to 3.21.x, you need to do the following:
You can start the mysqld
3.21 server with safe_mysqld
--old-protocol
to use it with clients from the 3.20 distribution.
In this case, the new client function mysql_errno()
will not
return any server error, only CR_UNKNOWN_ERROR
, (but it
works for client errors) and the server uses the old password() checking
rather than the new one.
If you are NOT using the --old-protocol
option to
mysqld
, you will need to make the following changes:
scripts/add_long_password
must be run to convert the
Password
field in the mysql.user
table to CHAR(16)
.
mysql.user
table (to get 62-bit
rather than 31-bit passwords).
MySQL 3.20.28 and above can handle the new user
table format
without affecting clients. If you have a MySQL version earlier than
3.20.28, passwords will no longer work with it if you convert the user
table. So to be safe, you should first upgrade to at least 3.20.28 and then
upgrade to 3.21.x.
The new client code works with a 3.20.x mysqld
server, so
if you experience problems with 3.21.x, you can use the old 3.20.x server
without having to recompile the clients again.
If you are not using the --old-protocol
option to mysqld
,
old clients will issue the error message:
ERROR: Protocol mismatch. Server Version = 10 Client Version = 9
The new Perl DBI
/DBD
interface also supports the old
mysqlperl
interface. The only change you have to make if you use
mysqlperl
is to change the arguments to the connect()
function.
The new arguments are: host
, database
, user
,
password
(the user
and password
arguments have changed
places).
Perl DBI
Class.
The following changes may affect requêtesin old applications:
HAVING
must now be specified before any ORDER BY
clause.
LOCATE()
have been swapped.
DATE
,
TIME
and TIMESTAMP
.
If you are using MySQL 3.23, you can copy the .frm
, the
.MYI
and the .MYD
files between different architectures
that support the same floating point format. (MySQL takes care of
any byte swapping issues).
The MySQL data `*.ISD' and the index files `*.ISM'
files) are architecture-dependent and in some case OS-dependent. If you
want to move your applications to another machine that has a different
architecture or OS than your current machine, you should not try to move
a database by simply copying the files to the other machine. Use
mysqldump
instead.
By default, mysqldump
will create a file full of SQL statements. You
can then transfer the file to the other machine and feed it as input to the
mysql
client.
Try mysqldump --help
to see what options are available.
If you are moving the data to a newer version of MySQL, you should use
mysqldump --opt
with the newer version to get a fast, compact dump.
The easiest (although not the fastest) way to move a database between two machines is to run the following commands on the machine on which the database is located:
shell> mysqladmin -h 'other hostname' create nom_base_de_donnees shell> mysqldump --opt nom_base_de_donnees \ | mysql -h 'other hostname' nom_base_de_donnees
If you want to copy a database from a remote machine over a slow network, you can use:
shell> mysqladmin create nom_base_de_donnees shell> mysqldump -h 'other hostname' --opt --compress nom_base_de_donnees \ | mysql nom_base_de_donnees
You can also store the result in a file, then transfer the file to the target machine and load the file into the database there. For example, you can dump a database to a file on the source machine like this:
shell> mysqldump --quick nom_base_de_donnees | gzip > nom_base_de_donnees.contents.gz
(The file created in this example is compressed.) Transfer the file containing the database contents to the target machine and run these commands there:
shell> mysqladmin create nom_base_de_donnees shell> gunzip < nom_base_de_donnees.contents.gz | mysql nom_base_de_donnees
You can also use mysqldump
and mysqlimport
to accomplish
the database transfer.
For big tables, this is much faster than simply using mysqldump
.
In the commands shown below, DUMPDIR
represents the full pathname
of the directory you use to store the output from mysqldump
.
First, create the directory for the output files and dump the database:
shell> mkdir DUMPDIR shell> mysqldump --tab=DUMPDIR nom_base_de_donnees
Then transfer the files in the DUMPDIR
directory to some corresponding
directory on the target machine and load the files into MySQL
there:
shell> mysqladmin create nom_base_de_donnees # create database shell> cat DUMPDIR/*.sql | mysql nom_base_de_donnees # create tables in database shell> mysqlimport nom_base_de_donnees DUMPDIR/*.txt # load data into tables
Also, don't forget to copy the mysql
database, since that's where the
grant tables (user
, db
, host
) are stored. You may have
to run commands as the MySQL root
user on the new machine
until you have the mysql
database in place.
After you import the mysql
database on the new machine, execute
mysqladmin flush-privileges
so that the server reloads the grant table
information.
MySQL apporte quelques extensions à la norme ANSI SQL 92 que vous ne trouverez probablement dans aucune autre base de données. Soyez conscient que si vous utilisez ces extensions, votre code ne sera pas portable sur une autre base SQL. Dans certains cas, vous pouvez écrire du code qui utilise ces extensions MySQL, mais qui est portable, en utilisant les commentaires de la forme /*! ... */
. Dans ce cas, MySQL va analyser puis exécuter le code de ce commentaire comme n'importe quelle commande MySQL, mais les autres serveur SQL les ignoreront. Par exemple :
SELECT /*! STRAIGHT_JOIN */ nom_colonne FROM table1,table2 WHERE ...
Voici la liste des extensions MySQL:
MEDIUMINT
, SET
, ENUM
et tous les types BLOB
et TEXT
.
AUTO_INCREMENT
, BINARY
, UNSIGNED
et ZEROFILL
.
BINARY
aux colonnes concernés, ou bien utiliser l'opérateur de transptypage BINARY
lors des comparaisons pour qu'elles prennent en compte l'ordre ASCII en cours sur l'hôte MySQL.
nom_base_de_donnees.nom_table
. Certains serveurs SQL propose la même fonctionnalité, mais l'appelle User space
. MySQL n'accepte pas les espaces de tables comme dans : create table ralph.my_table...IN my_tablespace
.
LIKE
est utilisable avec les colonnes de type numérique
INTO OUTFILE
et STRAIGHT_JOIN
dans les commandes SELECT
. SELECT
.
SQL_SMALL_RESULT
dans une commande SELECT
.
EXPLAIN SELECT
permet de voir de quelle manière les tables ont été regroupées.
INDEX
ou KEY
dans une commande CREATE TABLE
. CREATE TABLE
TEMPORARY
et IF NOT EXISTS
dans la commande CREATE TABLE
.
COUNT(DISTINCT liste)
lorsque 'liste' contient plus d'un élément.
CHANGE nom_colonne
, DROP nom_colonne
ou DROP INDEX
dans les commandes ALTER TABLE
. ALTER TABLE
.
IGNORE
dans les commandes ALTER TABLE
.
ADD
, ALTER
, DROP
ou CHANGE
dans les commandes ALTER TABLE
.
DROP TABLE
avec les mots clés IF EXISTS
.
DROP TABLE
.
LIMIT
dans les commandes DELETE
.
DELAYED
dans les commandes INSERT
et REPLACE
.
LOW_PRIORITY
dans les commandes INSERT
, REPLACE
, DELETE
et UPDATE
.
LOAD DATA INFILE
. Dans certains cas, cette syntaxe est compatibles avec la fonction LOAD DATA INFILE
d'Oracle. LOAD DATA
.
OPTIMIZE TABLE
. OPTIMIZE TABLE
.
SHOW
. SHOW
.
SET OPTION
. SET OPTION
.
GROUP BY
. Mais cela peut permettre d'accélérer quelques requêtes très spécifiques. 7.3.13 Fonctions à utiliser dans les clauses GROUP BY
.
||
et &&
(OR et AND, comme en langage C). Sous MySQL, ||
et OR
sont synonymes, tout comme le sont &&
et AND
. A cause de ce double emploi, MySQL n'accepte pas les opérateurs ANSI SQL ||
comme additionneur de chaînes; (utilisez à la place CONCAT()
).. Etant donné que CONCAT()
prend un nombre arbitraire d'arguments, il est facile de remplacer ||
.
CREATE DATABASE
ou DROP DATABASE
. CREATE DATABASE
%
est synonyme de MOD()
. C'est à dire que, N % M
est équivalent à MOD(N,M)
. %
est hérité du langage C, et permet la compatibilité avec PostgreSQL.
=
, <>
, <=
,<
, >=
,>
, <<
, >>
, <=>
, AND
, OR
ou LIKE
peuvent être utilisés dans les comparaisons de colonnes avec la clause FROM
dans les commandes SELECT
. Par exemple :
mysql> SELECT col1=1 AND col2=2 FROM nom_table;
LAST_INSERT_ID()
. mysql_insert_id
.
REGEXP
et NOT REGEXP
.
CONCAT()
ou CHAR()
avec plus d'un one argument. (Avec MySQL, ces fonctions peuvent prendre un nombre arbitraire d'arguments).
BIT_COUNT()
, ELT()
, FROM_DAYS()
, FORMAT()
, IF()
, PASSWORD()
, ENCRYPT()
, md5()
, ENCODE()
, DECODE()
, PERIOD_ADD()
, PERIOD_DIFF()
, TO_DAYS()
, ou WEEKDAY()
.
TRIM()
pour supprimer les espaces de début et fin de chaîne. ANSI SQL ne supporte que la suppression de caractères uniques.
GROUP BY
: STD()
, BIT_OR() et BIT_AND()
.
REPLACE
à la place de DELETE
+ INSERT
. REPLACE
.
FLUSH flush_option
.
Nous tÅchons de mettre MySQL aux normes ANSI SQL et ODBC SQL, mais dans certains cas, MySQL gère les choses de manière différente.
--
n'est pas un commentaire. 5.3.7 `--' comme début de commentaire.
VARCHAR
, les espaces de fin de chaînes sont supprimés à l'enregistrement. Bugs
.
CHAR
sont spontanément changées en colonne de type VARCHAR
. 7.6.1 Modifications automatiques de type de colonne.
REVOKE
pour supprimer les droits de la table. GRANT
.
Les fonctionnalités suivantes manquent dans la version courante de MySQL. La liste des fonctionnalités classées par ordre de priorité est disponible en ligne à : F Liste de voeux pour les versions futures de MySQL (la TODO).
La requête suivante ne fonctionne par encore sous MySQL:
SELECT * FROM table1 WHERE id IN (SELECT id FROM table2); SELECT * FROM table1 WHERE id NOT IN (SELECT id FROM table2);
Cependant, il est souvent possible de se passer d'une sous sélection :
SELECT table1.* FROM table1,table2 WHERE table1.id=table2.id; SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id where table2.id IS NULL
Pour les sous requêtes compliquées, vous pouvez toujours créer une table temporaire, et y appliquer votre requête.
MySQL ne supporte que INSERT ... SELECT ...
et REPLACE ... SELECT ...
Les sous sélections indépendantes ne seront disponibles qu'à partir de la version 3.24.0. Actuellement, vous pouvez toujours utiliser la fonction IN()
dans d'autres contextes.
SELECT INTO TABLE
MySQL ne supporte pas encore cette extension du SQL Orable.: SELECT ... INTO TABLE ...
. A la place, MySQL supporte la syntaxe de la norme ANSI SQL INSERT INTO ... SELECT ...
, ce qui est pratiquement la même chose.
Alternativement, vous pouvez utiliser SELECT INTO OUTFILE...
ou CREATE TABLE ... SELECT
pour résoudre votre problème.
Les transactions ne sont pas encore supportées par MySQL. Le serveur va bientôt accepter des opérations atomiques, ce qui permettra des transactions, mais sans le rollback. Avec les opérations atomiques, vous pourrez exécuter des groupes de commandes INSERT
/SELECT
/ avec n'importe quelle commande, et être sur qu'il n'y aura aucune interférence avec un autre thread. Dans ce contexte, vous n'aurez alors pas besoin de rollback. Actuellement, vous pouvez empêcher les autres threads d'interférer en utilisant les fonctions LOCK TABLES
et UNLOCK TABLES
. LOCK TABLES
.
Une fonctions enregistrée est un ensemble de commandes SQL qui peut être compilé et enregistré sur le serveur. Une fois fait, les clients peuvent se référer à cette fonction pour exécuter l'ensemble des commandes. Cela accélère le traitement des requêtes, car elles n'ont pas a être analysées, et moins d'information circule entre le client et le serveur. Il est aussi possible d'élever le niveau de conception, en bÅtissant des bibliothèques.
Un trigger est une fonction enregistrée qui est invoquées à chaque fois qu'un événement particulier survient. Par exemple, vous pourriez installer une fonction qui sera lancée à chaque fois qu'un enregistrement sera effacé dans une table de transaction, pour effacer automatiquement les informations correspondantes dans les tables de clients.
Lors de modifications ultérieures, MySQL sera capable de gérer les fonctions enregistrées, mais pas les triggers. En général, les triggers ralentissent le serveur, même pour des requêtes pour lesquelles ils ne sont pas appelés.
Pour savoir quand MySQL disposera des procédures enregistrées, sinon, F Liste de voeux pour les versions futures de MySQL (la TODO).
Remarque : les clés externes en SQL ne sont pas utilisées pour effectuer des regroupements de table, mais pour assurer l'intégrité référentielle. Si vous voulez lire des informations depuis plusieurs tables avec une commande SELECT
, c'est un regroupement !
SELECT * from table1,table2 where table1.id = table2.id;
JOIN
. 8.3.5 Utiliser des clés étrangères
La syntaxe FOREIGN KEY
de MySQL n'existe que pour la compatibilité avec les commandes CREATE TABLE
des autres bases SQL : elle n'a aucun effet. La syntaxe FOREIGN KEY
sans la partie ON DELETE ...
n'est utilisée que pour des raisons de documentation. Certaines applications ODBC l'utilise pour générer des clauses WHERE
automatiques, mais il est généralement simple à remplacer. FOREIGN KEY
est parfois utilisé comme contrainte, mais ce genre de vérification n'est pas nécessaire si les lignes ont été insérées dans l'ordre. MySQL ne supporte que ces clauses, car certaines applications en ont besoin (qu'elle fonctionne ou pas).
Avec MySQL, vous pouvez contourner le problème sans la clause ON DELETE ...
en ajoutant une commande DELETE
adéquate lors de l'effacement d'un enregsitrement d'une table qui a une clé externe. En pratique, c'est aussi rapide (voire plus), et beaucoup plus portable que les clés externes.
Dans un futur proche, nous allons implémenter FOREIGN KEY
de manière à sauver les informations dans la table de spécification, pour qu'elles soient accessibles par mysqldump
et ODBC.
Il y a tant de problèmes avec FOREIGN KEY
s qu'on ne sait même pas par ou commencer :
INSERT
et UPDATE
, et dans ce cas, presque toutes les vérifications dues à FOREIGN KEY
ne servent à rien, car vous insérez les informations dans le bon ordre, naturellement.
Le seul aspect intéressant de FOREIGN KEY
est de donner aux clients ODBC et quelques autres la possibilité de voir comment une table est connectée, et de l'utiliser pour créer un diagramme de connexion lors de la création d'applications.
MySQL gérera prochainement les définitions des FOREIGN KEY
, ce qui permettra aux clients de réclamer la structure de la connexion originale. La version courantes des fichiers ``.frm'' ne le permet pas.
MySQL ne supporte pas les vues, mais c'est sur la liste des fonctionnalités futures.
Sur d'autres bases SQL les commentaires commencent par ``--''. MySQL utilise ``#'' pour débuter un commentaire, même si mysql
supprime aussi les lignes qui commencent par ``--''. Vous pouvez aussi utiliser le style de commentaires C /* Ceci est un commentaire */
avec MySQL. Comments
.
MySQL n'accepte pas les commentaires commencant par ``--''; car ce style de commentaire obsolète a déjà causé de nombreux problèmes avec les requêtes générées automatiquement, lorsque la base utilise un code comme celui ci : la valeur de paiement va être placée à la place de !paiement!
:
UPDATE nom_table SET credit=credit-!paiement!
Mais que ce passe t il si la valeur de paiement
est négative?
Etant donné que 1--1
valide en SQL, nous pensons que les commentaires commencé par ``--'' sont une très mauvaise idée.
Si vous avez un programme SQL qui contient des commentaires avec le format ``--'' vous devriez utiliser:
shell> replace " --" " #" < Fichier-texte-avec-des-commentaires-zarbi | mysql database
A la place de l'habituel :
shell> mysql database < text-file-with-funny-comments.sql
Vous pouvez aussi utiliser la commande fichier ``in place'' pour remplacer les commentaires ``--'' par ``#'':
shell> replace " --" " #" -- text-file-with-funny-comments.sql
Retrouvez vos situation initiale avec :
shell> replace " #" " --" -- text-file-with-funny-comments.sql
SQL92. ODBC level 0-2.
COMMIT
/ROLLBACK
MySQL ne supporte pas COMMIT
-ROLLBACK.
Le problème tient à ce que COMMIT
-ROLLBACK
requiert une structure de table completement différente ce celle qui est utilisée actuellement. MySQL aurait besoin d'autres threads pour nettoyer automatiquement les tables et l'utilisation du disque serait augmentée d'autant. Ce qui ralentirait MySQL d'un facteur de 2 à 4. MySQL est beaucoup plus rapide que bien d'autres bases SQL (en général, de 2 à 3 fois plus rapide.). Une des raisons de cette vélocité est l'absence de COMMIT
-ROLLBACK
.
Pour le moment, nous sont concentrés sur l'implémentation du langage de serveur SQL (comme par exemple, les fonctions enregistrées). Avec ces fonctions, vous ne devriez faire appel au COMMIT
-ROLLBACK
que de manière exceptionnelle.
Les boucles que nécessite les transactions peuvent être remplacées avantageusement par les LOCK TABLES
, et vous n'aurez pas besoin de curseurs si vous pouvez modifier des enregistrements à la volée.
Les transactions et les curseurs sont sur la liste de voeux, mais elles ne sont pas prioritaires. Si nous les implémentons, ce sera sous la forme d'une option de CREATE TABLE
. Cela signifie que COMMIT
-ROLLBACK
ne fonctionnera qu'avec ces tables, ce qui ne pénalisera que les tables qui auront cette option, et non plus la base toute entière.
Ici, à TcX, nous avons un plus grand besoin d'une base de données rapide que d'une base de données généraliste. Si nous trouvons un moyen d'ajouter ces fonctionnalités sans perte de vitesse, nous le ferons sûrement. Pour le moment, nous avons d'autres choses plus importantes. Reportez tous à la liste des voeux pour savoir quelles sont les priorités (les clients de haut niveau de support peuvent cependant faire bouger les choses).
Le problème actuel est au niveau de ROLLBACK
. Sans le ROLLBACK
, vous pouvez effectuer des commandes de type COMMIT
en utilisant la commande LOCK TABLES
. Pour permettre le support du ROLLBACK
, MySQL devra enregistrer tous les vieux enregistrements qui sont modifiés ou effacé, pour pouvoir les restituer si un ROLLBACK
intervient. Pour les cas simples, ce n'est pas compliqué à mettre en place (l'utilitaire actuel isamlog
peut servir à ce propos), mais cela peut se révéler plus compliqué pour les commandes ALTER/DROP/CREATE TABLE
.
Pour éviter d'utiliser le ROLLBACK
, vous pouvez suivre la stratégie suivante :
LOCK TABLES ...
pour verrouiller les tables auxquelles vous accédez
UNLOCK TABLES
pour libérer la table.
Généralement, cette méthode est beaucoup plus rapide que les transactions, et le ROLLBACK
est souvent possible, mais pas toujours. Le seul point critique est que si le threads est tué au milieu de la modification, les verrous seront libérés, mais une partie des modifications ne sera pas faites.
Vous pouvez aussi utiliser les fonctions qui modifient un seul enregistrement à la fois. Vous pouvez créer des applications très efficaces avec la technique suivante :
Par exemple, lors vous modifiez les informations concernant un client, ne modifiez que les informations qui ont changées, et non pas celle qui sont restées constantes. La recherche des valeurs est faites avec la clause WHERE
de la commande UPDATE
. Si l'enregistrement a changé, on peut retourner au client une message du type : "Les informations n'ont pas été modifiées, car un autre utilisateur est en train de modifier les valeurs ". Alors, on affiche l'ancienne valeur et la nouvelle, ce qui permet à l'utilisateur de décider quelle version utiliser.
Cela fournit un mécanisme du genre ``verrouillage de colonne'' mais c'est en fait un peut mieux, car seule les colonnes qui en on besoin sont utilisées. Une commande UPDATE
ressemblera alors à ceci :
UPDATE tablename SET pay_back=pay_back+'différence de valeur'; UPDATE customer SET customer_date='date actuellee', address='nouvelle adresse', phone='nouveau numero de telephone', débit =débit + 'autre_débit' WHERE customer_id=id AND address='vieille addresse' AND phone='vieux numero de telephone';
Comme vous pouvez le voir, c'est une méthode très efficace, et qui fonctionne même si un autre client a changé la valeur entre temps.
Dans certains cas, l'utilisateur ont demandé le ROLLBACK
et/ou LOCK TABLES
dans le but de gérer des identifiants uniques dans des tables . Il vaut mieux utiliser le type de colonne AUTO_INCREMENT
et la fonction SQL LAST_INSERT_ID()
ou l' API C : mysql_insert_id()
. mysql_insert_id()
.
A TcX, nous n'avons jamais eu besoin d'un verrouillage de ligne, car nous avons toujours réussit à contourner le problème. Dans certains cas, le verrouillage de ligne était nécessaire, mais c'est très rarement le cas. Si vous voulez le verrouillage de ligne, utiliser un flag sur une colonne dans la table comme ci :
UPDATE nom_table SET row_flag=1 WHERE id=ID;
MySQL retourne 1, ce qui correspond au nombre de ligne affectées par la commande, si la ligne a été trouvée, et que le flag row_flag
n'était pas déjà à 1.
Vous pouvez considérer que MySQL traite la requête ci dessus de la manière suivante :
UPDATE nom_table SET row_flag=1 WHERE id=ID and row_flag <> 1;
MySQL dispose d'un système moderne mais original de droits d'accès. Cette section le décrit.
La fonction primaire du système de droits de MySQL est d'authentifier un utilisateur se connectant, et l'associer avec les droits d'utilisation des commandes select, insert, update et delete sur cette base.
Les fonctions secondaires inclus la possibilité d'accueillir un utilisateur anonyme, et de donner des droits particuliers à des fonctions spécifiques à MySQL LOAD DATA INFILE
et les opérations.
Il y a de grandes différences entre la gestion des noms d'utilisateur et mots de passe de MySQL, et celle de Unix ou de Windows.
-u
ou --user
. Cela signifie que vous ne pouvez sécuriser un serveur MySQL qu'en ayant un mot de passe pour chacun des utilisateurs. Sinon, n'importe quelle personne qui se connecte en utilisant n'importe quel nom, réussira à se connecter, si ce nom d'utilisateur n'a pas de mot de passe.
PASSWORD()et ENCRYPT()
dans la section 7.3.12 Fonctions diverses.
Les clients MySQL ont besoin d'un certains nombre de paramètres pour se connecter à un serveur MySQL : l'hôte qui abrite le serveur, le nom d'utilisateur et le mot de passe. Par exemple, le client mysql
peut être lancé avec la ligne suivante : (les arguments optionnels sont mis entre crochets ``['' et ``]''):
shell> mysql [-h host_name] [-u user_name] [-pyour_pass]
Il est aussi possible de remplacer respectivement les options -h
, -u
et -p
par--host=host_name
, --user=user_name
et --password=your_pass
. Notez bien qu'il n'y as pas d'espace entre -p
ou --password=
et le mot de passe qui le suit.
Note: Transmettre un mot de passe dans la ligne de commande n'est pas sécurisé ! N'importe quel utilisateur du système peut découvrir le mot de passe en tapant : ps auxww
.
4.15.4 Fichier d'options.
Par défaut, mysql utilise les valeurs suivantes :
localhost
, c'est à dire la machine locale.
-p
n'est pas précisé.
Ainsi, pour un utilisateur Unix joe
, les commandes suivantes sont équivalentes :
shell> mysql -h localhost -u joe shell> mysql -h localhost shell> mysql -u joe shell> mysql
D'autres clients MySQL se comportent de manière similaire :
Sous Unix, vous pouvez spécifier d'autres valeurs par défaut, lors de la connexion, ce qui vous évitera d'entrer les paramètres à chaque connexion. Cela peut être fait de diverses façons :
[client]
du fichier de configuration ``.my.cnf'' de votre dossier personnel. Les informations doivent être présentées comme suit :
[client] host=host_name user=user_name password=your_pass
MYSQL_HOST
. Le nom d'utilisateur MySQL peut être spécifié avec les variables USER
, LOGNAME
ou LOGIN
(bien que ces variables peuvent avoir déjà été réservé pour votre login de connexion, et ce ne serait pas conseillé de les changer). Le mot de passe sera spécifié dans la variable MYSQL_PWD
( mais ce n'est pas très sur, comme vous le verrez à la prochaine section).
Si les paramètres de connexion sont spécifiables de nombreuses manières, les valeurs spécifiées sur la ligne de commande ont priorité sur les valeurs enregistrées dans le fichier de configuration, et ces dernières ont priorité sur les variables d'environnement.
Il n'est pas conseillé d'exposer son mot de passe, ou de le stocker dans des endroits qui faciliterait sa connaissances par d'autres utilisateurs. Les méthodes de spécifications du mot de passe lors du lancement du programme client sont présentées ci-dessous, avec à chaque fois, les risques de la méthode :
-pyour_pass
ou --password=your_pass
. C'est très pratique, mais très dangereux, ca le mot de passe devient visible pour les commandes de statut du système (comme par exemple ps
) qui peut être invoqué pas d'autres utilisateurs. Les clients MySQL remplace le mot de passe par une ligne de zéro lors de la séquence d'initialisation, mais il y a quand même un temps très bref, où la valeur est écrite en clair).
-p
ou --password
(sans valeur spécifiée). Dans ce cas, le programme client va solliciter le mot de passe depuis la console :
shell> mysql -u user_name -p Enter password: ********
Le client renvoie les caractères``*'' à la console, au fur et à mesure que vous entrez votre mot de passe, ce qui fait que quelqu'un derrière votre épaule ne pourra pas le voir. La sécurité est donc renforcée par rapport à la méthode précédente, mais cela oblige à utiliser le client en mode interactif. Vous ne pourrez pas lancer le programme depuis un script.
[client]
du fichier de configuration ``.my.cnf'' de votre dossier home.
[client] password=your_pass
Si vous stockez votre mot de passe dans le fichier ``.my.cnf'', ce fichier ne doit pas être accessible en lecture ou en écriture ni au groupe, ni au monde. Assurez vous que le mode d'accès du fichier est 400
ou 600
.
4.15.4 Fichier d'options.
MYSQL_PWD
, mais cette méthode doit être considéré comme extrêmement dangereuse. Certaines options de ps
permettent d'avoir accès aux variables d'environnement des processus en cours, ce qui fait que votre mot de passe peut être parfaitement lisible. Même sur des systèmes qui n'ont pas cette version de ps
, il est fortement déconseillé de supposer qu'il n'y a pas d'autres méthode d'observation des processus.
L'un dans l'autre, la méthode la plus sûre est de fournir le mot de passe à la console, ou de spécifier le mot de passe dans le fichier ``.my.cnf'', correctement protégé.
Les droits sont conservés dans les tables user
, db
, host
, tables_priv
et columns_priv
de la base de données. Le serveur MySQL lis le contenu de ces tables au démarrage, et à chaque fois que c'est nécessaire, comme décrit dans la section 6.9 Prise en compte des modifications de droits.
Les noms utilisés dans ce manuel pour se référer aux droits de MySQL sont listés ci-dessous, avec le nom de la colonne associé à chaque droit dans la table de droits, et le contexte d'application du droit.
Les droits select, insert, update et delete permettent d'exécuter des opérations sur les lignes dans les tables existantes d'une base. Vous pouvez même exécuter certaines commandes SELECT
sans avoir accès à aucune base sur le serveur. Par exemple, vous pouvez utiliser mysql
comme une simple calculatrice :
mysql> SELECT 1+1; mysql> SELECT PI()*2;
Le droit index vous permet de créer ou de détruire des index.
Le droit alter vous permet d'utiliser la commande ALTER TABLE
.
Les droits create et drop vous permet de créer et détruire de nouvelles tables et bases.
Il faut bien remarquer que si vous donnez le droit de drop pour la base mysql
, un utilisateur pourra effacer la table des droits MySQL!
Le droit grant vous permet de donner des droits que vous possédez à un autre utilisateur.
Le droit file vous permet de lire et écrire des fichiers sur le serveur, en utilisant les commandes LOAD DATA INFILE
et SELECT ... INTO OUTFILE
. Tout utilisateur qui dispose de ce droit peut écrire ou lire des fichiers que MySQL peut écrire ou lire.
Les autres droits sont utilisés pour les opérations administratives, qui sont disponibles avec mysqladmin
. La table ci-dessous montre quelle droit donne accès à quelle commande mysqladmi
:
La commande reload
force le serveur à relire les tables de droits. La commande refresh
vide toutes les tables de la mémoire, et ouvre puis ferme les fichiers d'historique. flush-privileges
est un synonyme de reload
. Les autres commandes flush-*
exécutent des fonctions similaires à refresh
mais ne sont pas aussi limitées, et parfois même, elles sont préférables. Par exemple, si vous souhaitez uniquement enregistrer les fichiers d'historique, flush-logs
est mieux que refresh
.
La commande shutdown
éteint le serveur.
La commande processlist
affiche la liste des threads courant du serveur. La commande kill
arrête les threads du serveur. Vous pouvez toujours afficher et détruire les threads que vous possédez, mais vous devez avoir les droits de process pour afficher ou terminer les threads d'un autre utilisateur.
La meilleure stratégie est de ne donner des droits qu'à ceux qui en ont besoin, mais il faut être particulièrement prudents avec certains droits :
SELECT
.
mysql
peuvent être utilisés pour changer des mots de passe, ou tout autre droit d'accès. (Les mots de passes sont cryptés avant d'être enregistrés, ce qui empêche leur relecture. Mais avec les droits adéquats, un utilisateur peu scrupuleux peu les remplacer par d'autre mot de passe, et empêcher l'accès).
Il y a des limitations avec les droits MySQL:
MySQL s'assure que tous les utilisateurs peuvent faire ce qu'ils ont le droit de faire. Lorsque vous vous connectez à un serveur MySQL, le serveur détermine votre identité grÅce à l'hôte depuis lequel vous vous connectez, et le nom d'utilisateur que vous spécifiez.. Le système vous alloue alors les droits adéquats.
MySQL considère que le nom de l'hôte et le nom d'utilisateur sont suffisants pour vous identifier sans ambiguïté, car il y a peu de chance qu'un nom d'utilisateur soit utilisé par la même personne, depuis tous les hôtes sur Internet ! Par exemple, l'utilisateur bill
qui se connecte depuis whitehouse.gov
ne sera probablement pas la même personne que l'utilisateur bill
qui se connecte depuis microsoft.com
. MySQL vous permet de distinguer les deux utilisateurs, et de donner des droits différents pour le même nom d'utilisateur, mais pour des hôtes différents.
MySQL contrôle l'accès en deux temps :
Le serveur utilise les tables user
, db
et host
de la base mysql
pour conserver les informations de connexion et les droits. Les champs de ces tables sont les suivants :
Pour la deuxième étape d'accès, le serveur peut consulter éventuellement (si la requête implique des tables)les tables tables_priv
et columns_priv
. Les champs de ces tables sont les suivants :
Chaque table de droits contient les champs d'identification et de droits.
Les champs d'identification détermine le contexte d'application des droits. Par exemple, la table user
avec une ligne dont les champs Host,
User
ont les valeurs de 'thomas.loc.gov'
et 'bob'
seront utilisés pour identifier les connexions de bob
depuis thomas.loc.gov
. De la même façon, la table db
avec une ligne dont les champs Host
, User
et Db
sont respectivement 'thomas.loc.gov'
, 'bob'
et 'reports'
seront utilisés lors que bob
se connecte depuis host thomas.loc.gov
pour accéder à la base reports
. Les tables tables_priv
et columns_priv
contiennent les noms des tables et des tables / colonnes pour qui s'appliquent les droits.
Pour des raisons de vérifications d'accès, les comparaisons effectuées sur les colonnes Host
sont insensibles à la casse.. User
, Password
, Db
et Table_name
sont sensibles à la casse.. Column_name
est insensible à la casse depuis MySQL 3.22.12.
Les champs de droits indiques quels droits sont donnés, quelles commandes sont autorisées. Le serveur combine les informations des différentes tables pour construire une fiche complète de description des droits du serveur. Les règles utilisées pour cela sont décrites dans la section 6.8 Contrôle d'accès, étape 2 : vérification des requêtes.
Les champs d'identification sont des chaînes, déclarées comme ci-dessous. La valeur par défaut de chaque champs est la chaîne vide.
Dans les tables user
, db
et host
, tous les champs de droits sont déclarés comme des ENUM('N','Y')
- chaque champs peut prendre la valeur 'N'
ou 'Y'
, et la valeur par défaut est 'N'
.
Dans les tables tables_priv
et columns_priv
, Les champs de droits sont déclarés comme des SET
:
Présenté rapidement, le serveur utilises les tables de droits comme ceci :
user
détermine le droit de connexion. Pour les connexions autorisées, les droits globaux de l'utilisateurs sont précisés.
db
et host
sont utilisées ensembles :
db
détermine quelles bases sont accessibles à quels utilisateurs. Les champs de droits déterminent quels sont les droits autorisés.
host
est utilisée comme une extension de db
lorsque vous voulez qu'une ligne de db
s'applique à plusieurs hôtes. Par exemple, si vous voulez qu'un utilisateur soit capable d'accéder à la base depuis plusieurs hôtes différents, laissez le champs Host
de la table db
vide, puis ajoutez un enregistrement dans la table host
pour chaque hôte à autoriser. Ce mécanisme est décrit en détails dans la section 6.8 Contrôle d'accès, étape 2 : vérification des requêtes.
tables_priv
et columns_priv
sont similaires à la table db
, mais s'appliquent au niveau table et colonne, plutôt qu'au niveau base.
Notez bien que les droits administratifs (tels reload, shutdown, etc.) ne sont spécifiés que dans la tables user
. En effet, les opérations administratives sont des opérations sur le serveur lui-même, et ne sont pas spécifiques à une base de données : il n'y a pas de raison d'avoir ces privilèges dans d'autres tables. En fait, seule la table user
est consultée pour déterminer les droits administratifs.
Le droit file est spécifié seulement dans la table user
. Ce n'est pas un droit administratif, mais il n'est pas dépendant de la table, ou de la base en cours.
Le serveur mysqld
lit le contenu des tables de droits au démarrage. Les modifications des tables de droits ne prennent effets qu'à des moments précis, comme précisé dans la 6.9 Prise en compte des modifications de droits.
Lorsque vous modifiez le contenu des tables de droits, il es important de s'assurer que les modifications de droits produiront bien l'effet désiré. Il existe une aide pour comprendre ces erreurs, reportez vous à la section Security
.
Un outil d'analyse pratique est le script mysqlaccess
, qui est fournit gracieusement par Yves Carlier dans la distribution de MySQL. Lancez mysqlaccess
avec l'option --help
pour comprendre comment il fonctionne. Notez que mysqlaccess
utilise les droits des tables user
, db
et host
. Il ne prend pas en compte les droits sur les tables ou les colonnes.
Lorsque vous tentez de vous connecte à un serveur MySQL, le serveur accepte ou rejete votre tentative en fonction de votre identité, et de votre capacité à fournir le mot de passe correct. Dans le cas contraire, le serveur refuse complètement l'accès. Sinon, le serveur accepte la connexion, et passe en niveau 2, pour attendre les requêtes.
L'identité lors de la connexion est basé sur deux éléments :
La vérification de l'identité est faite en utilisant les trois champs d'identité de la table user
(Host
, User
et Password
). Le serveur n'acceptera une connexion que si il existe un enregistrement qui contienne votre hôte, votre nom d'utilisateur et votre mot de passe.
Les valeurs de la table user
peuvent être fournies avec les propriétés suivante :
Host
peut être un nom d'hôte, ou une adresse IP ou 'localhost'
pour indiquer la machine locale.
Host
.
Host
qui vaut '%'
accepte tous les hôtes. Host
vide est équivalent à to '%'
. Notez que ces valeurs accepte n'importe quel hôte qui peut créer une connexion avec votre serveur !
User
, mais vous pouvez le laisser vide, ce qui équivaudra à '%'
. Si un enregistrement de la table user
a un champs User
vide, cet utilisateur sera considéré comme anonyme (utilisateur sans nom) plutôt qu'étant l'utilisateur avec le nom spécifié par le client. Cela signifie que l'utilisateur vide sera utilisé ultérieurement pour toutes les vérifications de droits, durant toute la connexion.
Password
peut être laissé vide. Cela ne signifie pas que n'importe quel mot de passe sera accepté, mais que l'utilisateur doit se connecter SANS mot de passe.
Les valeurs de Password
qui ne sont pas vides représentent des mots de passe cryptés. MySQL ne conserve pas les mots de passe en clair, qui risqueraient ainsi d'être vu par n'importe qui. Lors de la connexion, le mot de passe fourni est crypté de la même manière que le mot de passe enregistré, et les deux valeurs sont comparées. Si les deux correspondent, le mot de passe fourni est le bon.
Les exemples suivants montrent différentes combinaisons des colonnes Host
et User
de la table user
:
Etant donné que l'on peut utiliser des jokers dans le champs Host
(i.e., '144.155.166.%'
pour accepter tout un sous domaine), il est possible que quelqu'un essaie d'exploiter ceci en prenant comme nom 144.155.166.petaouschnock.com
. Pour contrer ce genre de tentatives, MySQL n'accepte pas les noms d'hôtes qui commencent par des chiffres suivis d'un point. Ainsi, un hote du genre 1.2.foo.com
ne pourra jamais être accepté. Seule les IP numériques peuvent utiliser un joker.
Une connexion entrante peut disposer de plusieurs entrées dans la table user
. Par exemple, la connexion thomas.loc.gov
de fred
pouurait être acceptée plusieurs fois dans les exemples ci-dessus. Comment le serveur fait il pour choisir une entrée ou une autre ? Il résoud la question en triant les utilisateurs au moment du démarrage, et en lisant les entrées dans cet ordre trié. La première ligne qu'il trouve est alors la bonne.
La table user
fonctionne comme ceci. Supposons qu'elle ressemble à ceci :
+-----------+----------+- | Host | User | ... +-----------+----------+- | % | root | ... | % | jeffrey | ... | localhost | root | ... | localhost | | ... +-----------+----------+-
Lorsque le serveur lit la table, il classe les lignes en commencant par les hôtes les moins généraux ('%'
dans la colonne Host
signifie ``tous les hôtes'' et c'est le cas le plus général). Les lignes avec le même hôte sont classé en commencant par les utilisateurs les moins généraux (un utilisateur en blanc signifie ``tous les utilisateurs'' et c'est le cas le plus général. Une fois triée, la table ressemble à ceci :
+-----------+----------+- | Host | User | ... +-----------+----------+- | localhost | root | ... | localhost | | ... | % | jeffrey | ... | % | root | ... +-----------+----------+-
Lors d'une connexion, le serveur recherche parmi les lignes classées, et utilise la première ligne qui aille et l'utilise. Si la connexion entrante vient de l'hôte localhost
et de l'utilisateur jeffrey
, les premières lignes, avec 'localhost'
sont trouvées. Parmi celles-ci, la ligne avec le champs utilisateur vide correspond à la connexion. (la linge avec '%'/'jeffrey'
était aussi correcte mais elle apparaît plus tard dans la table).
Voici un autre exemple :. fonctionne comme ceci. Supposons que la table user
ressemble à ceci :
+----------------+----------+- | Host | User | ... +----------------+----------+- | % | jeffrey | ... | thomas.loc.gov | | ... +----------------+----------+-
Une fois triée, la table ressemble à ceci :
+----------------+----------+- | Host | User | ... +----------------+----------+- | thomas.loc.gov | | ... | % | jeffrey | ... +----------------+----------+-
Une connexion par l'hôte thomas.loc.gov
et l'utilisateur jeffrey
utilisera la première ligne, et la même connexion depuis whitehouse.gov
utilisera la seconde.
Une erreur commune est de penser que pour un nom d'utilisateur donné, toutes les lignes qui nomme explicitement cet utilisateur seront utilisées en premier par le serveur pour accepter la connexion. Ceci est tout simplement faux. L'exemple précédent l'illustre bien : la connexion depuis thomas.loc.gov
par jeffrey
n'utilise par la ligne contenant l'utilisateur 'jeffrey'
mais la ligne sans nom d'utilisateur.
Si vous avez des problèmes à vous connecte au serveur, afficher la table user
et trier la à la main, pour savoir quelle ligne est la première a accepter votre connexion.
Une fois que la connexion est établie, le serveur passe en niveau 2. Pour chaque requête entrante, le serveur va vérifier que les droits sont suffisants pour effectuer la requête, en fonction du type d'opération. C'est ici qu'interviennent les champs de droits des tables de droits. Ces droits peuvent être stockés dans les tables user
, db
, host
, tables_priv
ou columns_priv
tables. Ces tables sont gérées grÅce aux commandes GRANT
et REVOKE
. Reportez vous à la section Privileges
, dans laquelle les champs de ces tables sont présentés).
Les droits pris en charge par la table user
sont assignés globalement, et s'appliquent quelque soit la base de données courante. Par exemple, si la table user
donne les droits de delete, vous pouvez efface n'importe quelle base de donnée sur le serveur ! ! En d'autres termes, la table user
fourni les droits de super utilisateur, et il est avisé de ne donner ces droits qu'aux administrateurs du serveur. Pour les autres utilisateurs, il vaut mieux laisser les droits à 'N'
et donner des droits spécifiques sur les bases de données, avec les tables db
et host
.
Les tables db
et host
donnent des droits spécifiques aux bases de données. Les valeurs acceptées dans les champs sont les suivantes :
Host
et Db
de deux tables.
'%'
dans le champs Host
de la table db
signifie ``tous les hôtes.'' Une valeur vide pour Host
dans la table db
signifie ``consulte la table host
pour plus de détails.''
'%'
ou une chaîne vide dans le champs Host
de la table host
signifie `` tous les hôtes.''
'%'
ou une chaîne vide dans le champs Db
dans l'une des tables signifie ``toutes les bases de données.''
User
dans l'une des tables corresponde à l'utilisateur anonyme.
Les tables db
et host
sont lues et triées au démarrage du serveur (en même temps que la table user
). La table db
est triée en fonction des champs Host
, Db
et User
, et la table host
table est triée en fonction des champs Host
Db
. Tout comme pour la table user
, le trie met les valeurs les plus précises en premier, puis le plus larges. Lors de l'utilisation de la table, la première valeur qui correspond à l'utilisateur est utilisée.
Les tables de droits tables_priv
et columns_priv
contiennent les droits spécifiques aux droits par table et par colonne. Les valeurs des champs peuvent être les suivantes :
Host
et Db
de deux tables.
'%'
ou une chaîne vide dans le Host
de la table db
signifie ``tous les hôtes.''
Db
, Table_name
et Column_name
ne peuvent pas contenir de champs vide, ou de caractères spéciaux.
Les tables tables_priv
et columns_priv
sont triées en fonction des champs Host
, Db
et User
. Le tri est identique à celui de la table db
, mais étant donné que le champs Host
ne contient pas de caractère spéciaux, le tri est nettement plus simple.
Le processus de vérification de requête est décrit ci-dessous. (Si vous êtes familier avec la programmation de contrôle d'accès, vous remarquerez que la description qui suit est un peu simplifiée, par rapport aux algorithmes utilisés. En fait, la description est équivalente au code, et la différence sert simplement à rendre la description plus accessible).
Pour les requêtes administratives telles que shutdown, reload, etc..., le serveur ne vérifie les droits que dans la table user
, étant donné que c'est la seule qui spécifie les droits administratifs. La commande est exécutée si les droits sont disponibles, et sinon, la requête n'est pas autorisée. Par exemple, si vous voulez exécuter mysqladmin shutdown
mais que votre compte utilisateur dans la table user
n'a pas les droits de shutdown, l'autorisation n'est aps donnée, sans même vérifier les tables db
ou host
. (Etant donné que ces tables ne contiennent pas de colonne Shutdown_priv
, il n'y a pas besoin de passer en revue ces tables.)
Pour les requêtes liées aux bases de données, telles que insert, update, etc., le serveur commence par vérifier les droits globaux (droits de super utilisateur) en recherchant dans la table user
. Si il trouve des droits, l'exécution de la requête est autorisé. Si les droits globaux sont insuffisants, le serveur détermine les droits spécifiques à cette base en vérifiant les tables db
et host
:
db
une ligne qui corresponde à Host
, Db
et User
de l'utilisateur. Host
et User
ont été défini lors de la connexion au serveur. Le champs Db
prendre le nom de la base de données qui va être modifiée. Si il n'y a aucune entrée, l'autorisation n'est pas donnée.
Host
n'est pas laissé vide, cette ligne définit les droits de l'utilisateur, spécifiques à cette base.
Host
a été laissé vide, cela signifie que la table host
contient la liste des hôtes qui ont l'autorisation d'accéder à cette base. Dans ce cas, une nouvelle recherche est effectuée dans la table host
pour rechercher une ligne qui correspondent à Host
et Db
. Si aucune ligne n'est trouvée, alors l'accès n'est pas autorisé. Si une ligne est trouvée, les droits d'accès de cet utilisateur sont représentés par l'intersection des droits issus de la table db
et de la table host
, i.e., c'est à dire les droits qui sont à 'Y'
dans les deux lignes trouvées. (De cette manière, vous pouvez donner des droits généraux, et restreindre sélectivement en fonction des hôtes, grÅce à la table host
.)
Après avoir déterminé les droits spécifiques à la base de données, avec les tables db
et host
, le serveur les ajoutent aux droits globaux donnés par la table user
. Si le résultat de cette union autorise l'opération, la requête est exécutée. Sinon, le serveur vérifie les droits sur les tables et les colonnes dans les tables tables_priv
et columns_priv
et les ajoutent aux droits de l'utilisateur. l'accès est alors donné ou retiré en fonction du résultat.
Exprimé par une formule booléenne, la description précédente du calcul des droits est la suivante :
global privileges OR (database privileges AND host privileges) OR table privileges OR column privileges
Il n'est pas évident que si les droits globaux user
sont insuffisants pour l'opération demandée, le serveur va les ajouter dans les différentes tables qui conservent les droits. La raison est qu'une requête peut nécessiter plusieurs droits différents. Par exemple, la commande INSERT ... SELECT
requiert les droits d'insertion (insert) et de selection (select). Il se peut alors que les droits d'insertion soient disponible au niveau de la table, et que les droits de selection soient au niveau de la colonne. Dans ce cas, les droits de deux niveaux doivent être combinés pour autoriser la commande. D'où cette propagation de droits.
La table host
est utilisée pour avoir une liste de serveurs ``sécurisés''. A TcX, la table host
contenait la liste de toutes les machines du réseau local. Toutes ces machines avaient des autorisations d'accès sur le serveur.
Vous pouvez aussi utiliser cette table pour lister les serveurs qui ne sont pas sûrs. Par exemple, supposons que la machine public.votre.domaine
soit située dans une zone publique qui ne soient pas sûre. Vous pouvez alors accepter tous les hôtes du réseau, et exclure cette machine, comme ceci :
+----------------------+----+- | Host | Db | ... +----------------------+----+- | public.votre.domaine | % | ... (tous les droits à 'N') | %.your.domain | % | ... (tous les droits à 'Y') +-------------------**-+----+-
Bien entendu, il est plus sage de tester toutes les lignes des tables de droits (e.g., en utilisant mysqlaccess
) pour s'assurer que les droits sont bien donnés comme vous le souhaitez.
Lorsque mysqld
démarre, les tables de droits sont lu, et chargés en mémoire : ils sont alors effectifs.
Les modifications des tables de droits qui se font avec les requêtes GRANT
, REVOKE
, ou SET PASSWORD
sont immédiatement prises en compte.
Si vous modifiez les tables de droits manuellement (INSERT
, UPDATE
, etc.), vous devrez exécuter la commande FLUSH PRIVILEGES
ou lancer mysqladmin flush-privileges
pour indiquer au serveur qu'il faut qu'il relise les tables de droits. Sinon, les changements ne seront pas effectifs avant le prochain rechargement.
Lorsque le serveur remarque que les tables de droits ont été changées, les connexions courantes sont traitées comme suit :
USE nom_base_de_donnees
.
Les droits globaux et les mots de passes ne changent qu'à la prochaine connexion.
Après avoir installé MySQL, vous allez installer les premiers droits en exécutant l'utilitaire scripts/mysql_install_db
. 4.7.1 Introduction à l'installation rapide. Le script scripts/mysql_install_db
démarre le serveur mysqld
, puis initialise les tables de droits, qui contiendront alors les droits suivants :
root
est créé, c'est le super utilisateur, investi de tous les droits. Les connexions au serveur MySQL doivent être faites depuis l'hôte local. NB: Le super utilisateur initial a un mot de passe vide ce qui fait que n'importe qui peut se connecter sans mot de passe, et disposer de tous les droits.
'test_'
et aussi 'test'
. Les connections doivent être faites depuis l'hôte local. Cela signifie que quiconque se connecte depuis cet hôte peut être traité comme un utilisateur anonyme.
mysqladmin shutdown
ou mysqladmin processlist
.
NB: Les droits par défaut sont différents sous Windows. 4.12.4 Faire tourner MySQL sous Win32.
Etant donné que votre installation initialle est très ouverte, la première chose à faire est d'attribuer un mot de passe au root. Vous pouvez le faire simplement avec la commande suivante :
shell> mysql -u root mysql mysql> UPDATE user SET Password=PASSWORD(nouveau_mot_de_passe) WHERE user='root'; mysql> FLUSH PRIVILEGES;
Vous pouvez aussi utiliser la commande SET PASSWORD
:
shell> mysql -u root mysql mysql> SET PASSWORD FOR root=PASSWORD(nouveau_mot_de_passe);
Un autre moyen d'attribuer le mot de passe est de passer la commande mysqladmin
:
shell> mysqladmin -u root password nouveau_mot_de_passe
Notez bien que si vous modifiez un mot de passe dans la table user
directement avec la première méthode, vous devez faire relire les tables par le serveur avec la commande FLUSH PRIVILEGES
: dans le cas contraire, les modifications ne seront pas prises en compte.
Une fois que le mot de passe du root
a été affecté, vous devrez le fournir pour pouvoir vous connecter comme root
.
Vous pouvez aussi laisser le mot de passe du root
blanc, ce qui vous évitera d'avoir à le spécifier lors de la connexion, surtout si vous faites d'autres tests d'installation. Sinon, n'oubliez pas d'en assigner un lors du passege en production, pour ne pas créer des trous de sécurité.
Reportez vous au script scripts/mysql_install_db
pour voir fonctionner les privilèges par défaut. Vous pouvez utiliser ce script comme base, pour ajouter de nouveaux utilisateurs.
Si vous voulez que les privilèges par défaut soient différents de ceux présentés jusqu'à présent, modifiez le script mysql_install_db
avant de l'exécuter.
Pour recréer les tables de droits, effacez les fichiers ``*.frm'', ``*.ISM'' et ``*.ISD'' dans le dossier contenant le serveur mysql
. (ce dossier est nommé ``mysql'' dans le dossier du serveur. Ce dernier est affiché si avec la commande mysqld -help.
Alors, exécutez le script mysql_install_db
, éventuellement après avoir l'avoir édité.
NOTE IMPORTANTE : pour les versions de MySQL antérieures à 3.22.10, vous ne DEVEZ PAS effacer les fichiers ``*.frm''. Si vous l'avez fait par accident, vous devez remettre une copie (tirée de la distribution MySQL) avant d'exécuter mysql_install_db
.
Vous pouvez ajouter des utilisateurs de deux manières différentes : en utilisant la commande GRANT
ou en manipulant directement les tables de droits MySQL. La meilleure méthode est l'utilisation de la commande GRANT
, car elle est plus concise et est la source de moins d'erreur. Les exemples ci dessous montrent comment utiliser le client mysql
client pour ajouter un nouvel utilisateur. Ces exemples supposent que les droits ont été créé comme décrit dans la section précédente. Cela signifie notamment que pour faire des modifications, il vous faut être sur la machine qui fait tourner le serveur, vous devez vous connecter en tant que root
, et le root
doit avoir les droits d'insertion et de rechargement (insert et reload ). De plus, si vous avez changé le mot de passe du root
, vous devrez le spécifier pour pouvoir exécuter les commandes suivantes
Ajout d'un nouvel utilisateur
shell> mysql --user=root mysql mysql> GRANT ALL PRIVILEGES ON *.* TO monty@localhost IDENTIFIED BY 'quelquechose' WITH GRANT OPTION; mysql> GRANT ALL PRIVILEGES ON *.* TO monty@"%" IDENTIFIED BY 'something' WITH GRANT OPTION; mysql> GRANT RELOAD,PROCESS ON *.* TO admin@localhost; mysql> GRANT USAGE ON *.* TO dummy@localhost;
Ces commandes ajoutent 3 nouveaux utilisateurs
'quelquechose'
pour ce faire. Notez l'utilisation de la commande GRANT
pour les deux formes monty@localhost
et monty@"%"
. Si la ligne avec localhost
n'est pas ajoutée l'utilisateur anonyme qui a été créé par le script mysql_install_db
aura priorité lors de la connexion, car il sera plus spécifique. Il faut donc l'ajouter nommément pour pouvoir donner les bons droits à monty
.
localhost
sans mot de passe, et qui a les droits administratifs de reload et process. Cela va lui permettre d'exécuter les utilitaires mysqladmin reload
, mysqladmin refresh
et mysqladmin flush-*
, ainsi que mysqladmin processlist
. Aucun droit lié aux bases de données ne sont donnés. Ils pourront être donnés plus tard, avec des commandes GRANT
.
localhost
. Les privilèges globaux sont tous à 'N'
- le type spécial USAGE
vous permet de créer rapidement un utilisateur sans droits, et lui occtroyer plus tard.
Vous pouvez aussi ajouter ces informations avec des commandes INSERT
et en forcant le serveur à recharger ces tables.
shell> mysql --user=root mysql mysql> INSERT INTO user VALUES('localhost','monty',PASSWORD('something'), 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y') mysql> INSERT INTO user VALUES('%','monty',PASSWORD('something'), 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y') mysql> INSERT INTO user SET Host='localhost',User='admin', Reload_priv='Y', Process_priv='Y'; mysql> INSERT INTO user (Host,User,Password) VALUES('localhost','dummy',''); mysql> FLUSH PRIVILEGES;
Suivant la version de MySQL, vous pouvez avoir un nombre différent de 'Y'
dans les lignes ci-dessus (Les versions antérieures à 3.22.11 avaient moins de colonnes de droits.). Pour l'utilisateur admin
, la version plus pratique de la commande INSERT
est disponible à partir de la version 3.22.11.
Notez que pour créer un super utilisateur, il vous suffit de créer une ligne dans la table user
avec tous les privilèges mis à 'Y'
: aucune ligne n'est requise dans les tables db
ou host
.
La colonne de droit dans la table user
n'ont pas été explicitement fixée dans la dernière commande INSERT
(pour l'utilisateur dummy
), ce qui fait que ces colonnes ont une valeur par défaut de 'N'
. C'est le même comportement que pour la commande GRANT USAGE
.
L'exemple suivant ajoute un utilisateur custom
qui peut se connecter depuis les hôtes localhost
, server.domain
et whitehouse.gov
. Il veut pouvoir accéder à la base de données bankaccount
, mais uniquement depuis localhost
, à la base expenses
mais uniquement depuis whitehouse.gov
et à la base customer
depuis tous les hôtes Il veut avoir le même mot de passe pour toutes les connexions.
Pour donner ces droits à cet utilisateur, utilisez les commandes GRANT
suivantes :
shell> mysql --user=root mysql mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON bankaccount.* TO custom@localhost IDENTIFIED BY 'stupid'; mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON expenses.* TO custom@whitehouse.gov IDENTIFIED BY 'stupid'; mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON customer.* TO custom'%' IDENTIFIED BY 'stupid';
Pour donner ces droits à cet utilisateur en accédant directement aux tables de droits, utilisez les commandes suivantes :
shell> mysql --user=root mysql mysql> INSERT INTO user (Host,User,Password) VALUES('localhost','custom',PASSWORD('stupid')); mysql> INSERT INTO user (Host,User,Password) VALUES('server.domain','custom',PASSWORD('stupid')); mysql> INSERT INTO user (Host,User,Password) VALUES('whitehouse.gov','custom',PASSWORD('stupid')); mysql> INSERT INTO db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv, Create_priv,Drop_priv) VALUES ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y'); mysql> INSERT INTO db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv, Create_priv,Drop_priv) VALUES ('whitehouse.gov','expenses','custom','Y','Y','Y','Y','Y','Y'); mysql> INSERT INTO db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv, Create_priv,Drop_priv) VALUES('%','customer','custom','Y','Y','Y','Y','Y','Y'); mysql> FLUSH PRIVILEGES;
Les trois premières insertions ajoutent des lignes dans la table user
pour autoriser la connexion de custom
depuis les divers sites qu'il désire, mais ne lui donne aucune permission. (tous ses droits sont à 'N'
). Les trois insertions suivantes ajoutent des lignes dans la table db
pour donner des droits sur les bases bankaccount
, expenses
et customer
, mais uniquement pour des connexions avec des hôtes autorisés. Et, comme toujours lorsqu'on touche aux tables de droits, le serveur doit les recharger (avec FLUSH PRIVILEGES
) pour les prendre en compte.
Si vous désirez donner un droit spécifique à un utilisateur donnée, mais depuis n'importe quel hôte, utilisez la commande GRANT
suivante :
mysql> GRANT ... ON *.* TO myusername@"%.mydomainname.com" IDENTIFIED BY 'mypassword';
Pour faire la même chose avec une attaque directe des tables, faites ceci :
mysql> INSERT INTO user VALUES ('%.mydomainname.com', 'myusername', PASSWORD('mypassword'),...); mysql> FLUSH PRIVILEGES;
Vous pouvez aussi utiliser xmysqladmin
, mysql_webadmin
et even xmysql
pour insérer, modifier des valeurs dans les tables de droits. Vous pouvez trouvez ces utilitaires à http://www.mysql.com/Contrib/.
Les exemples des sections précédentes illustre un principe important : lorsque vous enregistrez des mots de passe non vide avec les commandes INSERT
ou UPDATE
, vous devez utiliser la fonction PASSWORD()
pour l'encrypter. En effet, la table user
conserve les mots de passe sous forme cryptée, et non pas en clair. Si vous oubliez ceci, vous pouvez vous retrouver avec des mots de passes tels que :
shell> mysql -u root mysql mysql> INSERT INTO user (Host,User,Password) VALUES('%','jeffrey','biscuit'); mysql> FLUSH PRIVILEGES;
Le résultat est que la valeur en clair 'biscuit'
est enregistrée dans la table user
. Lorsque l'utilisateur jeffrey
va tenter de se connecter au serveur, le client mysql
va crypter le mot de passe qui lui est fourni avec PASSWORD()
, et l'envoyer au serveur. Le serveur compare alors la valeur qui est stockées (qui est en clair 'biscuit'
) avec la même valeur, mais encryptée (qui ne sera pas 'biscuit'
). La comparaison échoue, et le serveur rejette al connexion.
shell> mysql -u jeffrey -pbiscuit test Access denied
Etant donné que les mots de passe doivent être crypté lorsqu'ils sont inséré dans la table user
, la commande INSERT
doit être spécifié comme suit :
mysql> INSERT INTO user (Host,User,Password) VALUES('%','jeffrey',PASSWORD('biscuit'));
Vous devez utiliser la fonction PASSWORD()
lorsque vous utilisez la clause SET PASSWORD
:
mysql> SET PASSWORD FOR jeffrey@"%" = PASSWORD('biscuit');
Si vous ajoutez un mot de passe avec la commande GRANT ... IDENTIFIED BY
ou avec la commande mysqladmin password
, la fonction PASSWORD()
n'est pas nécessaire. Ces deux méthodes crypte le mot de passe pour vous :
mysql> GRANT USAGE ON *.* TO jeffrey@"%" IDENTIFIED BY 'biscuit';
or
shell> mysqladmin -u jeffrey password biscuit
Note: PASSWORD()
dispose d'une encryption qui n'est pas la même que sous Unix. Il ne faut pas supposer que le mot de passe Unix et MySQL sont les mêmes, même si PASSWORD()
retourne la même valeur que celle qui est stockée dans le fichier de mot de passe de Unix.
6.2 Noms et mot de passe des d'utilisateurs MySQL.
"Access denied"
L'erreur " Access denied
" (accès refusé) peut survenir lors d'une tentative de connexion à MySQL. Voici une liste de problème type qui peuvent être la cause d'un tel comportement, et leur solution :
mysql_install_db
après avoir installé MySQL, pour créer les premières lignes dans les tables de droits ? Si non, faites le. 6.10 Droits initiaux. Testez les droits initaux en exécutant la commande suivante :
shell> mysql -u root test
Le serveur doit vous autoriser la connexion sans erreur. Assurez vous aussi que vous avez un fichier appelé ``user.ISD'' dans le dossier de MySQL. Généralement, il se trouve là : ``PATH/var/mysql/user.ISD'', Avec PATH
qui représente le chemin jusqu'à la racine de l'installation de MySQL.
shell> mysql -u root mysql
Le serveur autorisera la connexion car l'utilisateur MySQL root
n'a pas de mot de passe à l'origine. Etant donné que cela crée un gros risque au niveau de la sécurité de la base, affecter un mot de passe à l'utilisateur root
doit être une priorité lorsque vous créez les utilisateurs de votre serveur. Si, lors de la connexion en tant que root
, vous obtenez l'erreur suivante :
Access denied for user: '@unknown' to database mysql
Cela signifie que vous n'avez pas de ligne dans la table user
avec la valeur 'root'
dans la colonne User
et que mysqld
n'a pas pu trouver votre hôte dans cette table. Dans ce cas, vous devez redémarrer le serveur avec l'option --skip-grant-tables
et éditer les fichiers ``/etc/hosts'' ou ``\windows\hosts'' pour ajouter une ligne pour votre hôte.
mysql_fix_privilege_tables
? Si non, faites le. La structure des tables de droits a évolé avec la version 3.22.11 lorsque la commande GRANT
a été ajoutée.
INSERT
ou UPDATE
) et que vos modifications n'ont pas été prise en compte, n'oubliez pas qu'il faut exécuter une commande FLUSH PRIVILEGES
ou mysqladmin flush-privileges
pour forcer le serveur à recharger les nouvelles valeurs. Sinon, vos modifications n'auront pas d'effet jusqu'au prochain redémarrage du serveur. N'oubliez pas qu'après avoir modifié votre mot de passe root
, vous n'avez pas à le re entrer jusqu'à ce que vous exécutiez la commande FLUSH PRIVILEGES
car le serveur n'a pas encore noté que vous l'aviez modifié !
mysqld
avec l'option --skip-grant-tables
. Ensuite, vous pouvez changer les tables de droits MySQL et utiliser le script mysqlaccess
pour vérifier si les modifications ont bien l'effet désiré. Lorsque vous avez fini, lancez la commande flush-privileges
pour forcer l'utilisation des nouvelles tables de droits. Note: Recharger les tables annule l'option --skip-grant-tables
. Cela vous permet de dire au serveur quand commencer à utiliser les droits, sans le redémarrer.
mysql -u user_name nom_base_de_donnees
ou mysql -u user_name -pyour_pass nom_base_de_donnees
. Si vous etes capable de vous connecter avec le client mysql
, c'est qu'il y a un problème avec votre programme, et non pas dans les droits d'accès.. (Notez aussi qu'il n'y a pas d'espace entre l'option -p
et le mot de passe. Alternativement, vous pouvez utiliser --password=your_pass
pour spécifier votre mot de passe.)
PASSWORD()
pour changer de mot de passe avec les commandes INSERT
, UPDATE
ou SET PASSWORD
. Cette fonction n'est pas nécessaire avec la commande GRANT ... INDENTIFIED BY
ou avec la syntaxe mysqladmin password
. Reportez vous à la section Passwords
localhost
est un synonyme qui désigne votre machine locale, ou l'hôte de connexion par défaut. Cependant, les connexions à localhost
ne sont pas valables si vous utilisez MIT-pthreads (Les connexions localhost
utilisent les sockets Unix, qui ne sont pas supportées par MIT-pthreads). Pour contourner le problème sur ces systèmes, il préférable d'utiliser l'option --host
pour spécifier explicitement le nom de l'hôte. Cela va forcer le type de la connexion à TCP/IP. Dans ce cas, vous devez utiliser le vrai nom d'hôte de votre machine, et l'inscrire dans la table user
(Cela reste vrai même si vous exécutez un programme client sur la même machine que le serveur).
Access denied
lors d'une connexion au serveur avec l'option -u user_name nom_base_de_donnees
, vous pouvez avoir un problème avec la talbe user
. Vérifiez ceci en exécutant la commande mysql -u root mysql
puis la commande sui vante :
mysql> SELECT * FROM user;
Le résultat devrait contenir une ligne dont les colonnes Host
et User
correspondent au nom d'hôte de votre ordinateur et au nom d'utilisateur MySQL.
Access denied
apparaîtra si vous essayez de vous connecter, le message d'erreur affichera l'adresse de l'hôte de connexion, le nom d'utilisateur et si vous utilisez un mot de passe. Normalement, il ne devrait y avoir qu'une ligne de la user
qui corresponde exactement au nom d'hôte de votre ordinateur et au nom d'utilisateur
user
pour décrire votre machine hôte :
Host ... is not allowed to connect to this MySQL server
Vous pouvez régler ce problème en utilisant l'utilitaire mysql
(sur la machine server ! !) pour ajouter une ligne dans la table user
pour le nom d'hôte de votre ordinateur et le nom d'utilisateur. Si vous ne fonctionnez pas sous MySQL 3.22 et que vous ne savez pas quelle adresse IP ou quel nom d'hôte est celui de votre machine, il vaut mieux ajouter une ligne avec '%'
dans la colonne Host
et redémarrer le serveur avec l'option --log
option. Après avoir tenté de vous connecter depuis la machine client, l'historique vous indiquera qui s'est réellement connecté. Vous pouvez alors remplacer la ligne avec '%'
de la table user
par une ligne plus spécifique. Sinon, cela peut créer un trou de sécurité.
mysql -u root test
fonctionne mais que mysql -h your_hostname -u root test
retourne une erreur Access denied
, alors c'est que vous n'avez pas entrer le nom de votre hôte dans la table user
. Un problème récurent est que la colonne Host
de la table user contient un nom d'hôte général, mais la résolution de nom retourne un nom de domaine complet, et vice-versa. Par exemple, si vous avec une ligne qui contient 'tcx'
dans la table user
, mais que votre DNS dit à MySQL que votre nom d'hôte est 'tcx.subnet.se'
, la ligne ne correspondra pas. Essayez d'ajouter une ligne dans la table user
qui contienne l'adresse IP numérique de votre hôte, dans la colonne Host
. (Alternativement vous pouvez aussi ajouter une ligne dans la table user
avec une valeur dans la colonne Host
qui contienne un caractère joker (par exemple, 'tcx.%')
. Cependant, c'est une pratique non sécurisée, qui peut provoquer des problèmes de sécurité.
mysql -u user_name test
fonctionne mais mysql -u user_name other_nom_base_de_donnees
ne fonctionne pas, c'est que vous n'avez pas d'entrée pour la colonne other_nom_base_de_donnees
de la table db
.
mysql -u user_name nom_base_de_donnees
fonctionne lorsqui'il est exécuté sur la machine server, mais que mysql -u host_name -u user_name nom_base_de_donnees
ne fonctionne pas lorsqu'il est utilisé sur une machine client, c'est que la machine client n'est pas listée dans la table user
ou la table db
.
Access denied
, effacez toutes les lignes de la table user
qui possède un joker (``%'' ou ``_')'dans la colonne Host.
Une erreur récurrente est d'insérer une ligne du type Host
='%'
et User
='quidam'
, en pensant que cela va vous permettre de vous connecter depuis la machine localhost
. La raison qui fait que ceci ne fonctionne pas est que les droits par défaut contiennent une ligne qui est Host
='localhost'
et User
=''
. Or, la ligne qui a Host
='localhost'
est plus spécifique que '%'
, et donc, sera utilisée de préférence à celle utilisée lors de la connexion de depuis localhost
! La procedure correcte est d'insérer un deuxième ligne avec Host
='localhost'
et User
='some_user'
, ou d'effacer les lignes avec Host
='localhost'
et User
=''
.
db
ou host
:
Access to database denied
Si l'entrée sélectionnée dans la table db
a une colonne Host
vide, assurezvous qu'il y a au moins une entrée correspondante dans la table host
qyu spécifie à quel hôte s'applique ces droits. Si vous avez une erreur en utilisant la commande SELECT ... INTO OUTFILE
or LOAD DATA INFILE
, c'est que vous n'avez peut être pas les droits file.
mysqld
avec les options de debugging (par exemple, --debug=d,general,query
). Cette option affichera les hôtes et nom d'utilisateur des connexions, ainsi que des informations concernant les commandes exécutées. Reportez vous à la section G.1 Debugguer un serveur MySQL.
mysqldump mysql
. Comme toujours, pensez à poster votre problème avec l'utilitaire mysqlbug
. Dans certains cas, vous devrez redémarrer mysqld
avec l'option --skip-grant-tables
pour pouvoir faire le dump.
Lorsque vous vous connectez à un serveur MySQL, vous utiliserez en règle générale un mot de passe. Le mot de passe sera transmis crypté lors de la connexion, et non pas en clair.
Toutes les informations suivantes seront transmises en clair, ce qui fait que quiconque observe la connexion peut lire les informations. Si vous êtes concerné par les problèmes de sécurité, vous pouvez utiliser le protocole compressé (à partir de MySQL 3.22) pour rendre les choses plus difficile. Pour complexifier encore la lecture, vous pouvez installer ssh
(http://www.cs.hut.fi/ssh). Ce protocol fourni un cryptage de la connexion TCP/IP entre le client MySQL et me serveur MySQL.
Pour sécuriser un système MySQL, il est fortement recommandé de suivre les recommandations suivantes :
mysql -u other_user nom_base_de_donnees
si other_user
n'a pas de mot de passe. C'est une stratégie standard dans les applications clients/serveur. Vous pouvez changer les mots de passe de tous les utilisateurs en éditant le script mysql_install_db
puis en l'exécutant, ou bien avec la commande root
suivante :
shell> mysql -u root mysql mysql> UPDATE user SET Password=PASSWORD('new_password') WHERE user='root'; mysql> FLUSH PRIVILEGES;
root
Unix. mysqld
peut être exécuté par n'importe quel utilisateur. Vous pouvez aussi créer un nouvel utilisateur mysql
augmenter la sécurité. Si vous utilisez mysqld
à partir d'un compte Unix autre que le root, vous n'avez pas à changer l'utilisateur the root
dans la table user
, car les noms d'utilisateur MySQL n'ont rien à voir avec ceux d'Unix. Vous pouvez éditer le script mysql.server
pour lancer mysqld
avec un autre utilisateur. Généralement, on le fait avec la commande su
. Pour plus de détails, @pref{Changing MySQL user}.
root
Unix dans le script mysql.server
, assurez vous que ce fichier n'est lisible que par le root
.
mysqld
est le seul à avoir les droits d'écriture / lecture dans le dossier des bases de données.
mysqladmin processlist
dévoile le texte de toutes les commandes en cours d'exécution, ce qui fait que tout ceux qui ont ce droit, ont vue sur les commandes du type UPDATE user SET password=PASSWORD('not_secure')
. mysqld
garde toujours une connexion de libre pour les utilisateurs qui ont le droit de process, afin que le root
MySQL puisse toujours se connecter et s'assurer du bon fonctionnement des connexions en cours.
mysqld
! Pour sécuriser un peu ceci, tous les fichiers généré par SELECT ... INTO OUTFILE
ne sont lisibles par tous, mais non modifiables. Le droit de file peut aussi être utilisé pour lire un fichier quelconque sur le serveur. Cela permet notamment de lire le fichier ``/etc/passwd'' dans une table, et de le lire avec SELECT
.
--secure
de mysqld
devrait être suffisante pour sécuriser les noms d'hôtes. Dans toues les cas, méfiez vous des jokers dans les noms d'hôtes.
Les options suivantes affectent la sécurité :
gethostbyname()
sont vérifiées pour s'assurer qu'elle correspondent bien à l'hôte original. Cela rend plus difficile de simuler un hôte. Cette option effectue aussi un nettoyage hygiénique des hôtes. Cette option a été enlevée par défaut dans la version MySQL 3.21 car elle peut ralentir le serveur, à cause du temps de résolution. MySQL 3.22 conserve les noms d'hôtes qu'il a déjà résolu dans un cache.
mysqladmin reload
.)
Host
doivent contenir des valeurs nuémriques, ou bien localhost
.
mysqld
doivent être faites avec les sockets Unix. Cette option n'est pas disponibles pour les systèmes qui utilisent les MIT-pthreads, car MIT-pthreads ne supporte pas les sockets Unix.
Une chaîne est une séquence de caractères, entourée par des guillemets simples (`''') ou doubles(`""'). Par exemple :
'une chaîne' "une autre chaîne"
A l'intérieur d'une chaîne, on trouve des séquences spéciales. Celles-ci commencent avec le caractère backslash (``\''), dit aussi caractère d'échappement. MySQL reconnaît les séquences suivantes :
Within a string, certain sequences have special meaning. Each of these sequences begins with a backslash known as the escape character. MySQL recognizes the following escape sequences:
\0
ASCII 0 (NUL
) le caractère nul.
\n
Une nouvelle ligne.
\t
Une tabulation.
\r
Un retour chariot.
\b
Un effacement.
\'
Un guillemet simple (``''').
\"
Un guillemet double (``"'').
\\
Un backslash (``\'').
\%
Un pourcentage ``%''. Cela permet de rechercher le caractère `%' dans un contexte ou il pourrait etre considéré comme un caractère spécial.
\_
Un souligné ``_'' Cela permet de rechercher le caractère ``_'dans un contexte ou il pourrait etre considéré comme un caractère spécial.'
Il y a plusieurs façons d'introduire des guillemets dans une chaîne.
La commande SELECT
ci-dessous montre comment fonctionne les guillemets et le caractère d'échappement.
mysql> SELECT 'bonjour', '"bonjour"', '""bonjour""', 'bonj''our', '\'bonjour';
+---------+-----------+-------------+----------+----------+ | bonjour | "bonjour" | ""bonjour"" | bonj'our | 'bonjour | +---------+-----------+-------------+----------+----------+ mysql> SELECT "bonjour", "'bonjour'", "''bonjour''", "bonj""our", "\"bonjour"; +---------+-----------+-------------+----------+----------+ | bonjour | 'bonjour' | ''bonjour'' | bonj"our | "bonjour | +---------+-----------+-------------+----------+----------+ mysql> SELECT "Voici\nQuatre\nLignes\nDistinctes"; +--------------------+ | Voici Quatre Lignes Distinctes | +--------------------+
Pour ajouter des valeurs binaires dans un BLOB, les caractères suivants doivent être représenté par des séquences spéciales :
NUL
ASCII 0. Représentation : ``\0'' (un backslash et un caractère ASCII ``0'' ).
\
ASCII 92, backslash. Représentation : ``\\''.
'
ASCII 39, guillemet simple. Représentation : ``\'''.
"
ASCII 34, guillemet double. Représentation : ``\"''.
1221 0 -32
294.42 -32032.6809e+10 148.00
MySQL supporte les valeurs hexadécimales. Dans un contexte numérique, elles se comportent comme des entiers (précision 64bits). Dans un contexte de chaînes, elles se comportent comme des chaînes binaires dont chaque paire de digits seront converti en caractère.
mysql> SELECT 0xa+0 -> 10 mysql> select 0x5061756c; -> Paul
Les chaînes hexadécimales sont souvent utilisées avec ODBC pour donner des valeurs aux colonnes BLOB.
NULL
NULL
signifie : ``aucune information''. Cette valeur est différente de 0 ou de la chaîne vide.
NULL
est parfois représenté par \N
quand on utilise un fichier d'import ou d'export (LOAD DATA INFILE
, SELECT ... INTO OUTFILE
). Cf section LOAD DATA
.
1e
, car un expression telle que 1e est ambiguÎ. Le nom peut être interprété comme une expression (1e + 1) ou comme le nombre 1e+1.
Nom_tab ou Nom_base. Nom_tab pour faire référence à un nom de colonne, à moins que cela puisse être ambiguÎ. Par exemple, si les tables t1 et t2 contiennent chacune la colonne c, et que lors d'un SELECT, les deux tables soient utilisées. Dans ce cas, c est ambiguÎ, car elle n'est pas unique dans les tables utilisées, et il faut alors préciser la colonne en précisant t1.c et t2.c. De la même manière, si deux bases de données contiennent chacune une table nommée t, il faudra préciser la base de données utilisée, en notant : db1.t.col1 et db2.t.col2.
Dans la syntaxe .Nom_tab. Nom_col, on suppose que la table Nom_tab est disponible dans la base de données courante. Cette syntaxe est autorisée pour assurer la compatibilité avec ODBC, car certains programmes compatible ODBC ajoute le préfixe point
``.'' aux noms des tables.
SELECT * FROM ma_table WHERE MA_TABLE.col=1;
mysql> SELECT Nom_col FROM Nom_table AS a WHERE a.Nom_col = 1 OR A. Nom_col = 2;
M
Indique la taille maximale d'affichage. La taille maximale autorisée par défaut est 255.
D
S'applique aux types à virgule flottante, et précise le nombre de chiffre après la virgule.
Crochets (``['' et ``]'') indique que cet argument est optionnel.
NB : Il est toujours possible de spécifier ZEROFILL
pour une colonne. MySQL ajoutera alors automatiquement l'attribut UNSIGNED
à la colonne.
TINYINT[(M)] [UNSIGNED] [ZEROFILL]
Un très petit entier. Signé, il couvre l'intervalle -128
à 127
; non signé, il couvre 0
à 255
.
SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
Un petit entier. Signé, il couvre l'intervalle -32768
à 32767
; non signé, il couvre 0
à 65535
.
MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
Un entier de taille intermédiaire. Signé, il couvre l'intervalle -8388608
à 8388607
; non signé, il couvre 0
à 16777215
.
INT[(M)] [UNSIGNED] [ZEROFILL]
Un entier de taille normale. Signé, il couvre l'intervalle -2147483648
à 2147483647
; non signé, il couvre 0
à 4294967295
.
INTEGER[(M)] [UNSIGNED] [ZEROFILL]
Un synonyme pour INT
.
BIGINT[(M)] [UNSIGNED] [ZEROFILL]
Un entier de grande taille. Signé, il couvre l'intervalle -9223372036854775808
à 9223372036854775807
; non signé, il couvre 0
à 18446744073709551615
.
NB : toutes les opérations arithmétiques effectuée en interne, utilise des BIGINT
signés ou DOUBLE
, donc il ne faut pas utiliser les grands entiers non signé au delà de 9223372036854775807
(63 bits), hormis pour les fonctions sur les bits.
NB : les opérations -
, +
et * utiliseront des BIGINT , même lorsque les arguments seront des entiers. Cela signifie que la multiplication de deux grands entiers (ou le résultat de fonction qui retourne des entiers) peut avoir des résultats surprenants, si le résultat est supérieur à 9223372036854775807
FLOAT(precision) [ZEROFILL]
Un nombre à virgule flottante. Il est obligatoirement signé. precision
peut prendre les valeurs de 4 ou 8. FLOAT(8)
est un nombre à précision double. Ces types sont identiques aux types FLOAT
et DOUBLE
décrit ci-dessous, mais leur précision peut être paramétrée. Avec
MySQL 3.23, ce sont de vrais nombres à virgule flottante, alors qu'avec les anciennes versions, FLOAT(precision)
n'avait que 2 décimales. Cette syntaxe a été ajoutée pour assurer la compatibilité ODBC.
FLOAT[(M,D)] [ZEROFILL]
Un nombre à virgule flottante, en précision simple. Il est toujours signé. Les valeurs sont comprises -3.402823466E+38
et -1.175494351E-38
.
DOUBLE[(M,D)] [ZEROFILL]
Un nombre à virgule flottante, en précision double. Il est toujours signé. Les valeurs sont comprises -1.7976931348623157E+308
et 2.2250738585072014E-308.
DOUBLE PRECISION[(M,D)] [ZEROFILL]
REAL[(M,D)] [ZEROFILL]
Des synonymes pour DOUBLE
.
DECIMAL(M,D) [ZEROFILL]
Un nombre à virgule flottante. Il est toujours signé. Il se comporte comme une colonne CHAR
. Il n'est pas paqué, c'est à dire que le nombre est stocké comme une chaîne de chiffre. Chaque chiffre, le signe moins, la virgule occupe un caractère. Si D vaut 0, le nombre n'aura pas de décimales, ni de virgule. La taille maximale pour les décimales est la même que pour les DOUBLE
, mais en il peut être limité par le choix de of M
et D
. Avec MySQL 3.23, M
n'inclut plus le signe moins``-'', ni la virgule des nombres décimaux (norme ANSI SQL.).
NUMERIC(M,D) [ZEROFILL]
Un synonyme pour DECIMAL
.
DATE
Une date. L'intervalle valide de date va de '1000-01-01'
à '9999-12-31'
. MySQL affiche les DATE
avec le format , mais il est possible d'affecter des DATE
en utilisant indifféremment des chaînes ou des nombres.
DATETIME
Une combinaison de date et d'heure. L'intervalle valide va de '1000-01-01 00:00:00'
to '9999-12-31 23:59:59'
. MySQL affiche DATETIME
avec le format 'YYYY-MM-DD HH:MM:SS',
mais il est possible d'affecter des DATETIME
en utilisant indifféremment des chaînes ou des nombres.
'1970-01-01 00:00:00'
à quelque part, durant l'année 2037. MySQL affiche les TIMESTAMP
avec les format YYYYMMDDHHMMSS
, YYMMDDHHMMSS
, YYYYMMDD
ou YYMMDD
, suivant que M
vaut 14
(ou absent), 12
, 8
ou 6
, mais il est possible d'affecter des TIMESTAMP
en utilisant indifféremment des chaînes ou des nombres. Une colonne de type TIMESTAMP
est très pratique pour enregistrer des dates et heures lors d'un INSERT
ou UPDATE
, car cette colonne sera automatiquement mis à la date et heure de l'opération la plus récente, si aucune valeur n'est précisée. Il est aussi possible d'affecter l'heure courante en assignant la valeur NULL
à une colonne de type . ( 7.2.6 Types date et heure)
TIME
Une mesure de l'heure. L'intervalle valide est '-838:59:59'
à '838:59:59'
. MySQL affiche TIME
au format 'HH:MM:SS', mais il est possible d'affecter des TIME
en utilisant indifféremment des chaînes ou des nombres.
YEAR
Un an. L'intervalle valide est 1901
à 2155
, et 0000
. MySQL affiche YEAR
au format YYYY,
mais il est possible d'affecter des YEAR
en utilisant indifféremment des chaînes ou des nombres}(Le type YEAR
est nouveau en MySQL 3.22.)
CHAR(M) [BINARY]
Une chaîne de caractère de taille fixe, et toujours complétée à droite par des espaces. M
va de 1 à 255 caractères. Les espaces supplémentaires sont supprimés lorsque la valeur est retournée dans une requête. Les tris et comparaisons effectués sur des valeurs de type CHAR
sont insensibles à la casse, à moins que le mot clé BINARY
soit précisé.
VARCHAR(M) [BINARY]
Une chaîne de caractère de longueur variable. Les espaces en fin de chaîne sont supprimés lorsque la chaîne est stockée (ce n'est pas conforme à la norme ANSI SQL). Va de 1 a 255 caractères . Les tris et comparaisons effectués sur des valeurs de type VARCHAR
sont insensibles à la casse, à moins que le mot clé BINARY
soit précisé. Voir aussi la section 7.6.1 Modifications automatiques de type de colonne.
TINYBLOB
TINYTEXT
Un objet BLOB
ou TEXT
avec une longueur maximale de 255 (2^8 - 1). Voir aussi la section 7.6.1 Modifications automatiques de type de colonne.
BLOB
TEXT
Un objet BLOB
ou TEXT
avec une longueur maximale de 65535 (2^16 - 1). 7.6.1 Modifications automatiques de type de colonne.
MEDIUMBLOB
MEDIUMTEXT
Un objet BLOB
ou TEXT
avec une longueur maximale de 16777215 (2^24 - 1). 7.6.1 Modifications automatiques de type de colonne.
LONGBLOB
LONGTEXT
Un objet BLOB
ou TEXT
avec une longueur maximale de 4294967295 (2^32 - 1). 7.6.1 Modifications automatiques de type de colonne.
ENUM('value1','value2',...)
Une énumération. Un objet chaîne peut prendre une des valeurs contenue dans une liste de valeur 'value1'
, 'value2'
, ...
, ou NULL
. Une ENUM
peut avoir un maximum de 65535 valeurs distinctes.
SET('value1','value2',...)
Un ensemble. Un objet chaîne peut prendre une ou plusieurs valeurs, chacun de ces valeur devant être contenue dans une liste de valeurs 'value1'
, 'value2'
, ...
. Un SET
peut prendre jusqu'à 64 éléments.
Voici la liste des espaces mémoire requis, par type.
Column type | Storage required |
TINYINT | 1 byte |
SMALLINT | 2 bytes |
MEDIUMINT | 3 bytes |
INT | 4 bytes |
INTEGER | 4 bytes |
BIGINT | 8 bytes |
FLOAT(4) | 4 bytes |
FLOAT(8) | 8 bytes |
FLOAT | 4 bytes |
DOUBLE | 8 bytes |
DOUBLE PRECISION | 8 bytes |
REAL | 8 bytes |
DECIMAL(M,D) | M bytes (D +2, if M < D )
|
NUMERIC(M,D) | M bytes (D +2, if M < D )
|
Column type | Storage required |
DATETIME | 8 bytes |
DATE | 3 bytes |
TIMESTAMP | 4 bytes |
TIME | 3 bytes |
YEAR | 1 byte |
Column type | taille requise |
CHAR(M) | M octets, 1 <= M <= 255
|
VARCHAR(M) | L +1 bytes, avec L <= M et 1 <= M <= 255
|
TINYBLOB , TINYTEXT | L +1 octets,
where L < 2^8
|
BLOB , TEXT | L +2 octets,
where L < 2^16
|
MEDIUMBLOB , MEDIUMTEXT | L +3 octets,
where L < 2^24
|
LONGBLOB , LONGTEXT | L +4 octets,
where L < 2^32
|
ENUM('value1','value2',...) | 1 ou 2 octets, suivant le nombre de valeur dans l'énumeration (65535 au maximum) |
SET('value1','value2',...) | 1, 2, 3, 4 ou 8 octets, suivant le nombre de membre de l'ensemble (64 membres au maximum) |
Les types VARCHAR
, BLOB
et TEXT
sont des types à longueur variable, dont taille de stockage dépend plus de la valeur qui leur est assignée que de leur taille maximale. Par exemple, une colonne de type VARCHAR(10)
peut contenir une chaîne de 10 caractères aux maximum. La taille réelle nécessaire est la longueur de la chaîne, plus 1 octet, qui stockera la taille réelle de la chaîne. Par exemple, la chaîne 'abcd'
occupe 5 octets.
Les types BLOB
et TEXT
ont besoin de 1, 2, 3 ou 4 octets pour stocker la taille de la colonne, en fonction du type.
Si une table possède au moins une colonne de longueur variable, l'enregistrement sera aussi de longueur variable. Il faut noter que lorsqu'une table est créée, MySQL peut, sous certaines conditions, changer le type d'une colonne de longueur variable en un type de colonne de longueur fixe, et vice-versa. Pour plus de détails, 7.6.1 Modifications automatiques de type de colonne.
La taille d'un objet ENUM
est déterminé par le nombre d'énumération différentes. 1 octet est suffisant pour décrire une énumération qui a jusqu'à 255 valeurs différentes ; 2 octets sont nécessaires décrire une énumération qui aurait jusqu'
La taille d'un objet SET
est déterminé par le nombre d'élément distinct qu'il contient. Si la taille d'un SET
est N, le SET
occupera (N+7)/8
octets, arrondi aux entiers 1,2,3,4, ou 8 octets. Un ensemble peut contenir jusqu'à 64 éléments.
Tous les types entiers disposent d'un attribut optionnel UNSIGNED
. Les valeurs non signées sont utilisées quand les nombres utilisé sont uniquement positifs, ou bien lorsqu'il faut pouvoir manipuler des nombres un peu plus grand de normalement.
Tous les types numériques disposent d'un attribut optionnel ZEROFILL
. Cette option force l'affichage de tous les zéros non significatifs. Ainsi, dans une colonne de type INT(5) ZEROFILL
, 4 sera affiché : 00004.
Quand une valeur trop grande est affectée à une colonne, MySQL limitera cette valeur au maximum qu'il peut stocker dans la colonne.
Par exemple, soit une colonne de type INT
qui accueille des nombres dans l'intervalle -2147483648
to 2147483647.
Lorsqu'on tente d'inserer -9999999999
dans cette colonne, MySQL utilisera automatiquement la plus petite valeur possible, soit -2147483648
. De même, Lorsqu'on tente d'inserer 9999999999
dans cette colonne, MySQL utilisera automatiquement la plus grande valeur possible, soit 2147483647.
Si une colonne est de type INT UNSIGNED
, la taille de la colonne est la même, mais les extrémités sont différentes. Lors d'une tentative d'insertion, -9999999999
et 9999999999
deviendront respectivement 0
et 4294967296
.
Ces conversions implicites sont signalées comme des alertes (``warnings''), lors des requêtes incluant ALTER TABLE
, LOAD DATA INFILE
, UPDATE
et INSERT
multi-lignes.
La taille maximale (M
) et le nombre de décimales (D
) sont utilisées lors du formatage et des calculs de la taille maximale d'une colonne.
MySQL tentera d'enregistrer n'importe quelle valeur, du moment que cette dernière peut être contenue dans la colonne, et malgré le dépassement de limite d'affichage. Par exemple, une colonne de type INT(4)
peut afficher 4 caractères. Il est cependant possible d'insérer une valeur qui a plus que 4 chiffres, telle que 12345
. La taille d'affichage est dépassée, mais 12345
est bien dans l'intervalle autorisé pour un INT
. Donc, MySQL va enregistrer la valeur de 12345
. Lors d'une requête, MySQL retournera bien la vraie valeur, c'est à dire . 12345
Le type DECIMAL
peut être considéré comme un type numérique (puisqu'il est synonyme de NUMERIC
), mais ce type est en fait enregistré comme une chaîne. Un caractère est utilisé pour chaque chiffre, pour la virgule et pour le signe moins``-''. Si D
vaut 0, DECIMAL
et NUMERIC
ne contiennent ni virgule, ni partie décimale.
La taille maximale d'une valeur DECIMAL
est la même que celle d'un DOUBLE
, mais elle peut dépendre des choix de M
et D
. Par exemple, un DECIMAL
déclaré tel que indique DECIMAL(4,2)
que la valeur maximale aura 2 chiffres après la virgule. Etant donné la façon avec laquelle le type DECIMAL
est enregistré, ce DECIMAL
sera compris entre-.99
to 9.99
, ce qui est nettement moins que les valeurs accessibles avec un DOUBLE
.
Pour éviter certains problèmes d'arrondissement, MySQL ajuste toujours les valeurs qu'il enregistre au nombre de décimale de la colonne. Ainsi, pour une colonne de type FLOAT(8,2)
., le nombre de décimale est 2. Donc, un nombre tel que 2.333
sera arrondi à 2.33
, puis enregistré.
Les types date et heure sont DATETIME
, DATE
, TIMESTAMP
, TIME
et YEAR
. Chacun dispose d'un intervalle de validité, et une valeur ``zéro'', qui peut être utilisé pour indiquer une valeur illégale.
Voici quelques considérations générales à garder à l'esprit quand on travaille avec les types date et heure :
'98-09-04'
), plutôt que dans l'ordre mois-jour-année ou l'ordre jour-mois-année utilisés habituellement. (ie '09-04-98'
, '04-09-98'
).
Column type | ``Zero'' value |
DATETIME | '0000-00-00 00:00:00'
|
DATE | '0000-00-00'
|
TIMESTAMP | 00000000000000 (length depends on display size)
|
TIME | '00:00:00'
|
YEAR | 0000
|
'0'
ou 0
,qui sont plus facile à écrire.
NULL
par MyODBC 2.50.12 et mieux, car ODBC ne peut pas manipuler de telle valeur.
Les types DATETIME
, DATE
et TIMESTAMP
sont proches. Cette section décrit leur caractéristiques, et montre en quoi ils sont similaires, et en quoi ils sont différents.
Le type DATETIME
est utile pour manipuler en même temps une date et une heure. . MySQL retourne et affiche les valeurs de type DATETIME
au format 'YYYY-MM-DD HH:MM:SS'.
L'intervalle valide pour le type DATETIME
est '1000-01-01 00:00:00'
à '9999-12-31 23:59:59'
. (``valide`` signifie que des valeurs anciennes pourrait fonctionner, mais qu'il n'y a aucune garantie).
Le type DATE
est utilisé pour manipuler simplement une date, sans l'heure. MySQL retourne et affiche les valeurs de type DATE
au format 'YYYY-MM-DD'
L'intervalle valide pour le type DATE
est '1000-01-01'
à '9999-12-31'
Le type TIMESTAMP
est utilisé automatiquement lors de requête , avec la valeur courante de date et d'heure. Si il y a plusieurs colonnes de type TIMESTAMP
, seule la première sera automatiquement mise à jour.
La datation automatique intervient sur la première colonne de type TIMESTAMP
, et dans les conditions suivantes :
INSERT
ou LOAD DATA
UPDATE
de valeur (Il est important de noter qu'une requête UPDATE
qui affecterait la même valeur que celle qui est déjà affectée dans la colonne, alors la colonne TIMESTAMP
ne sera pas mise à jour, car MySQL va ignorer la requête, par souci d'efficacité.)
TIMESTAMP
est explicitement mise à NULL.
Dans le cas où il y a plusieurs colonnes de type TIMESTAMP
, il est possible d'affecter la valeur courante de date et d'heure, en affectant la valeur NULL
ou NOW()
.
Il est possible d'affecter n'importe quelle date à une colonne de type TIMESTAMP
, en lui affectant explicitement la valeur désirée. Cela est vrai pour toutes les colonnes de type TIMESTAMP
, y compris la première. Par exemple, il est possible d'utiliser une colonne de type pour enregistrer le moment de création de la ligne, mais qui ne sera plus changé par la suite.:
Ou alors, il est aussi simple d'utiliser une colonne de type DATETIME
, qui sera initialisé à l'aide de la commande NOW()
, et qui ne sera plus jamais modifiée.
TIMESTAMP
couvre un espace de temps qui commence en 1970 et se termine quelques par en 2037, avec un précision d'une seconde. Ses valeurs sont affichée comme des nombres.
Le format utilisé par pour retourner les valeurs de type dépendent de la taille de l'affichage, comme présenté ci dessous. Un complet affiche 14 chiffres, mais il est possible de n'afficher qu'une partie.
Column type | Display format |
TIMESTAMP(14) | YYYYMMDDHHMMSS
|
TIMESTAMP(12) | YYMMDDHHMMSS
|
TIMESTAMP(10) | YYMMDDHHMM
|
TIMESTAMP(8) | YYYYMMDD
|
TIMESTAMP(6) | YYMMDD
|
TIMESTAMP(4) | YYMM
|
TIMESTAMP(2) | YY
|
Toutes les colonnes de type ont besoin de la même quantité de mémoire, quelque soit le format d'affichage. Les formats d'affichage les plus courants sont le 6, le 8, le 12 et le 14. Il est possible d'imposer une taille arbitraire au format d'affichage au moment de la création de la table, mais 0 et toutes les valeurs supérieures à 14 seront ramenées à 14. Les valeurs impaires entre 1 et 13 sont arrondies au nombre entier pair supérieur.
Il est possible d'affecter des valeurs de type DATETIME
, DATE
et TIMESTAMP
en utilisant n'importe lequel des formats suivants :
'YYYY-MM-DD HH:MM:SS'
ou 'YY-MM-DD HH:MM:SS'
. Les '-' et ' :' ne sont pas obligatoires, et n'importe quel caractère non numérique. Par exemple, '98-12-31 11:30:45'
, '98.12.31 11+30+45'
, '98/12/31 11*30*45'
et '98@12@31 11^30^45' sont équivalents.
'YYYY-MM-DD'
ou 'YY-MM-DD'
. Les '-' et ' :' ne sont pas obligatoires, et ils peuvent être remplacé par quel caractère non numérique. Par exemple, '98-12-31'
, '98.12.31'
, '98/12/31'
et '98@12@31'
sont équivalents.
'YYYYMMDDHHMMSS'
ou 'YYMMDDHHMMSS'
, en supposant que cette chaîne a bien un sens en tant que date. Par exemple, '19970523091528'
et '970523091528
seront comprises comme '1997-05-23 09:15:28'
.Au contraire, '971122459015'
n'est pas valide (le nombre de seconde n'est pas valide), et sera remplacé par : '0000-00-00 00:00:00'
.
'YYYYMMDD'
or 'YYMMDD'
, en supposant que cette chaîne a bien un sens en tant que date. Par exemple, '19970523'
et '970523'
seront comprises comme '1997-05-23'
.Au contraire, '971332'
n'est pas valide (le nombre de mois et de jour ne sont pas valides), et sera remplacé par : '0000-00-00'
.
YYYYMMDDHHMMSS
or YYMMDDHHMMSS
, en supposant que cette chaîne a bien un sens en tant que date. Par exemple, 19830905132800
et 830905132800
seront comprises comme '1983-09-05 13:28:00'
YYYYMMDD
or YYMMDD
, en supposant que cette chaîne a bien un sens en tant que date. Par exemple, 19830905132800
et 830905132800
seront comprises comme '1983-09-05 13:28:00'
DATETIME
, DATE
or TIMESTAMP
, comme NOW()
or CURRENT_DATE.
Toutes les valeurs de type DATETIME
, DATE
ou TIMESTAMP
sont converties automatiquement en ``zero'' du même type ('0000-00-00 00:00:00'
, '0000-00-00'
ou 00000000000000
).
Pour les valeurs spécifiées au format chaîne avec des délimiteurs, il n'est pas nécessaire de préciser les deux chiffres pour les mois ou les jours. Par exemple, '1979-6-9'
et '1979-06-09'
sont identiques. De la même façon, pour les valeurs spécifiées au format chaîne avec des délimiteurs, il n'est pas nécessaire de préciser les deux chiffres pour les heures, minutes ou secondes. Ainsi, '1979-10-30 1:2:3'
et '1979-10-30 01:02:03'
sont identiques.
Les valeurs spécifiée au format nombre doivent avoir 6, 8, 12 ou 14 chiffres. Si le nombre a 8 ou 14 chiffres, MySQL utilisera respectivement le format YYYYMMDD
ou YYYYMMDDHHMMSS
, où l'année sera représentée par les quatre premiers chiffres. Si le nombre a 6 ou 12 chiffres, MySQL utilisera respectivement le format YYMMDD
or YYMMDDHHMMSS
, où l'année sera représentée par les deux premiers chiffres. Si le nombre n'a pas le bon nombre de chiffre, il sera complété avec des zéros non significatif (placés avant le premier chiffre), jusqu'à correspondre à une taille analysable.
Les valeurs non délimitées, sont interprétées en fonction de leur longueur. Si la chaîne fait 8 ou 14 caractères, l'année sera considérée comme ayant 4 chiffres. Sinon, l'année n'aura que les deux premiers chiffres. La chaîne est interprétée de gauche à droite, en lisant successivement l'année, le mois, le jour, l'heure, la minute et la seconde, dans la mesure où la chaîne est suffisamment longue. Cela implique qu'il ne faut pas utiliser de chaîne de moins de 6 caractères. Par exemple, la chaîne '9903'
, qui pourrait s'interpréter mars 1999, sera remplacée par la date ``zéro''. En effet, est capable de trouver l'année (99) et le mois (03) mais pas le jour (00), et donc cette valeur n'est pas valide.
Les colonnes de type TIMESTAMP
enregistre les dates avec la précision maximum, quelque soit la taille d'affichage. Cela a plusieurs implications :
TIMESTAMP(4)
ou TIMESTAMP(2)
. Sinon, la valeur ne sera pas valide, et donc, remplacée par ``zéro''.
TIMESTAMP
ne causera pas de perte d'information : elles seront simplement cachées.
TIMESTAMP
soient en précision maximale, la seul fonction qui opère directement sur la valeur enregistrée dans la base est UNIX_TIMESTAMP()
. Les autres fonctions utilisent la valeur formatée. Cela signifie qu'il n'est pas possible d'utiliser une fonction telle que HOUR()
ou SECOND()
à moins que la partie significative de TIMESTAMP
soit inclus dans la valeur formatée. Par exemple, la partie HH
d'une valeur de type TIMESTAMP
ne sera pas affichée, à moins que la taille de l'affichage soit au moins de 10. Ainsi, utiliser la fonction sur une valeur de type de taille inférieure à 10 risque de retourner une valeur incohérente.
Il est possible d'affecter des valeurs de type date dans une variable d'un autre type date. Cependant, cela peut engendrer des altérations ou des pertes d'informations. :
DATE
dans une variable de type DATETIME
ou TIMESTAMP
, la partie heure du résultat est mis à '00:00:00'
, car la valeur DATE
ne contient aucune information d'heure.
DATETIME
ou TIMESTAMP
dans une variable de type DATE
, la partie heure du résultat est perdue , car la valeur DATE
ne contient aucune information d'heure.
DATETIME
, DATE
et TIMESTAMP
. En effet, pour le même format d'acquisition, les différents types n'ont pas le même intervalle de validité. Par exemple, TIMESTAMP
ne peut contenir de valeur antérieure à 1970
ou postérieure à 2037
. Cela signifie qu'une date telle que as '1968-01-01'
, tout en étant valide pour les types DATETIME
or DATE
, n'est pas valide pour le type TIMESTAMP
et sera transformée en 0, lors de l'affectation à un tel objet.
Attention aussi aux erreurs de spécifications :
'10:11:12'
ressemble à une heure, à cause des délimiteurs " : ". Mais, utilisé dans un contexte de date, il peut aussi être interprété comme la date'2010-11-12'
. De même, la valeur '10:45:15'
sera convertie en 0, car 45 ,'est pas un mois valide.
00-69
sont considéré comme 2000-2069
.
70-99
sont considéré comme 1970-1999
.
TIME
MySQL retourne et affiche les valeurs de type TIME
aux formats 'HH:MM:SS'
ou 'HHH:MM:SS'
. Les valeurs de type TIME
vont de '-838:59:59'
à '838:59:59'
. Le nombre d'heure peut être rendu aussi grand afin de pouvoir représenter les heures du jour, mais aussi de faire des calculs de différence d'heure entre deux jours, ce qui conduit à des durée très supérieures à 24h, voire même des valeurs négatives.
Les valeurs de type TIME
peuvent être définies de nombreuses manières différentes :
'HH:MM:SS'
. Les :' ne sont pas obligatoires, et ils peuvent être remplacé par n'importe quel caractère non numérique. Par exemple, , '10:11:12'
et '10.11.12'
sont équivalents..
'HHMMSS'
, en supposant qu'elle est un sens en tant que date. Par exemple, '101112'
sera interpreté comme '10:11:12'
, mais '109712'
n'est pas valide et deviendra '00:00:00'
.
HHMMSS
, en supposant que cela ait un sens. Par exemple, 101112
vaudra . '10:11:12'
DATETIME
, DATE
or TIMESTAMP
, comme NOW()
or CURRENT_DATE.
Pour les valeurs de type TIME
spécifiées au format chaîne avec des délimiteurs, il n'est pas nécessaire de préciser les deux chiffres pour les heures, minutes ou secondes. Ainsi, '8:3:2'
et '08:03:02'
.sont identiques.
Attention aux affections de valeurs courtes dans une colonne de type TIME
. MySQL interprète les valeurs en supposant que les chiffres de gauche sont les secondes (MySQL interprète les valeurs de type TIME
comme des intervalles de temps, plutôt qu'une date). Par exemple, '11:12'
, '1112'
et 1112
pourraient être confondues avec '11:12:00'
(12 minutes après 11 heures), mais MySQL le comprend comme '00:11:12'
(11 minutes, 12 seconds). De même, '12'
et 12
representent '00:00:12'
.
Toutes les valeurs de TIME
, qui sont hors de l'intervalle de validité sont ramenées à la valeur valide la plus proche. Ainsi, '-850:00:00'
et '850:00:00'
sont respectivement converties en'-838:59:59'
et '838:59:59'
.
Toutes les valeurs invalides de TIME
sont converties en '00:00:00'
. Il faut bien savoir que '00:00:00'
est une valeur de TIME
valide. Ainsi, si est stocké dans une table, il est impossible de dire si cela provient d'une erreur, ou si il a été affecté à cette valeur.
YEAR
Le type YEAR
sert à représenter les années sur un octet.
MySQL retourne et affiche les YEAR
au format YYYY
: L'intervalle de validité est de 1901
à 2155
.
Les valeurs de type YEAR
peuvent être définies de nombreuses manières différentes :
1901
à 2155
.
1901
à 2155
.
00'
à '99'. Les valeurs de '00'
à '69'
et de'70'
à '99'
seront converties en valeurs de type YEAR
, dans les intervalles respectifs de 2000
à 2069
et de 1970
à 1999
.
1
à 99. Les valeurs de 1
à 69
et de70
à 99
seront converties en valeurs de type YEAR
, dans les intervalles respectifs de 2000
à 2069
et de 1970
à 1999
. Il faut bien noter que ce format diffère légèrement du précédent, car il n'est pas possible de passer un nombre égal à 0, pour obtenir l'année 2000. Il faut spécifier une chaîne, '0'
ou '00'
, sinon MySQL retournera 0000
DATETIME
, DATE
or TIMESTAMP
, comme NOW()
.
Toutes les valeurs invalides de YEAR
sont converties en 0000
.
Les types chaînes sont CHAR
, VARCHAR
, BLOB
, TEXT
,
ENUM
et SET
.
CHAR
et VARCHAR
Les types CHAR
et VARCHAR
sont similaires, mais ils diffèrent par la manière dont ils sont stockés.
Les valeurs de type CHAR
sont de longueur fixée. La longueur est déclarée lors de la création de la table. Cette longueur peut aller de 1 à 255. Quand une valeur de type CHAR
est enregistrée, elle est complétée à gauche par des espaces. Lorsque MySQL retourne cette valeur, ces espaces sont effacés.
Les valeurs de type VARCHAR
sont de longueur variable. Une longueur maximum est déclarée lors de la création de la table. Cette longueur peut aller de 1 à 255. Quand une valeur de type CHAR
est enregistrée, seul les caractères utiles sont enregistrés, plus un octet pour enregistrer la taille de la chaîne. Les ne sont pas complétée à gauche par des espaces, mais les espaces en début de valeurs sont effacés lors de l'enregistrement (cette fonction d'effacement des espaces à l'enregistrement n'est pas spécifiée dans ANSI SQL).
Lors de l'affectation d'une valeur de type CHAR
ou VARCHAR
dans une colonne trop petite, la valeur est tronquée à la taille de la colonne.
La table ci dessous illustre les différences de taille entre les deux types :
Value | CHAR(4) | Storage required | VARCHAR(4) | Storage required |
'' | ' ' | 4 bytes | '' | 1 byte |
'ab' | 'ab ' | 4 bytes | 'ab' | 3 bytes |
'abcd' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
'abcdefgh' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
Les valeurs retournées seront les mêmes, car dans tous les cas, les espaces situés en début de chaîne seront effacées
Les valeurs de type CHAR
et VARCHAR
sont triées et comparées sans tenir compte de la casse, à moins que l'option BINARY
ai été activée lors de la création de la table. Cette option signifie que cette colonne sera triée et comparée en tenant compte de la casse, et en fonction de l'ordre de la table ASCII de la machine qui supporte MySQL.
Le mode est contagieux : Cela signifie que si une colonne de type binaire est utilisée dans une expression, la comparaison tiendra compte de la casse.
MySQL peut changer spontanément les types de colonne lors de la création d'une table.. 7.6.1 Modifications automatiques de type de colonne.
BLOB
et TEXT
Un BLOB
est un binary long object
, c'est à dire un objet binaire long, qui peut contenir une certaine quantité d'information. Les quatre types TINYBLOB
, BLOB
, MEDIUMBLOB
et LONGBLOB
ne diffèrent que par leur taille maximum. Voir 7.2.1 Tailles nécessaires pour le stockage de types de colonnes.
Les quatre types TINYTEXT
, TEXT
, MEDIUMTEXT
t LONGTEXT
correspondent aux quatre types BLOB
et ont les mêmes tailles maximum, et les mêmes conditions de stockage. La seule différence entre les types BLOB
et TEXT
tient aux tris et aux comparaisons : les tris et comparaisons tiennent compte de la casse, dans le cas des TEXT
, et n'en tiennent pas compte, dans le cas des BLOB
. En d'autres termes, un TEXT
est un BLOB
insensible à la casse.
Lors de l'affectation d'une valeur de type BLOB
ou TEXT
dans une colonne trop petite, la valeur est tronquée à la taille de la colonne.
En général, on peut considérer qu'une colonne de type TEXT
est une colonne de type VARCHAR
, aussi grande que désiré. De la même manière, on peut considérer qu'une colonne de type BLOB
est une colonne de type VARCHAR BINARY
, aussi grande que possible. Les différences sont :
BLOB
et TEXT
pour les version de MySQL 3.23.2 ou plus récentes. Les anciennes versions ne le supporte pas.
BLOB
t TEXT
, contrairement aux colonnes de type VARCHAR
.
BLOB
and TEXT
columns cannot have DEFAULT
values.
BLOB
t TEXT
n'ont pas d'option DEFAULT
.
MyODBC utilise le type LONGVARBINARY
pour le type BLOB
et LONGVARBINARY
pour TEXT
.
Parce que les types peuvent être extrêmement grands, il y a certaines contraintes à leur utilisation :
GROUP BY
ou ORDER BY
sur une colonne de type BLOB
ou TEXT
, il faut commencer par convertir la colonne dans un type à longueur fixe. Pour cela, on utilise la fonction SUBSTRING
. Par exemple :
mysql> SELECT commentaires FROM Nom_table , SUBSTRING(commentaires,20) as souschaîne ORDER BY souschaîne;
Si SUBSTRING n'est pas utilisé, le tri portera uniquement sur les max_sort_longueur
premiers octets de la colonne. Par défaut, max_sort_longueur
vaut 1024, et cette valeur peut être changée en utilisant l'option , lors du démarrage de MySQL. Il est possible d'utiliser la clause GROUP sur un BLOB
or TEXT
, en spécifiant la position de la colonne, et en utilisant un alias. Par exemple :
mysql> select id,substring(blob_col,1,100) FROM Nom_table GROUP BY 2; mysql> select id,substring(blob_col,1,100) as b FROM Nom_table GROUP BY b;
Il faut bien noter que chaque valeur de type est représentée de manière interne par un objet alloué. Contrairement aux autres objets, pour qui l'espace mémoire est réservé à la création de la table.
ENUM
Le type est ENUM
une chaîne, dont la valeur est choisi dans une liste de valeurs autorisées, et spécifiées à la création de la table.
Cette valeur peut prendre les valeurs (""
) ou NULL
sous certaines conditions :
ENUM
( par exemple, une chaîne qui ne serait pas dans la liste des valeurs autorisées), une chaîne vide est insérée à la place, afin d'indiquer une erreur.
ENUM
est déclarée NULL
, NULL
sera alors une valeur valide pour cette colonne, et la valeur par défaut sera aussi NULL
. Si une ENUM
est déclarée NOT NULL
, la valeur par défaut sera le premier élément de la liste de valeurs autorisées.
Chaque énumération a un index.
SELECT
pour rechercher des lignes qui auraient une valeur ENUM
invalide :
mysql> SELECT * FROM Nom_table WHERE enum_col=0;
NULL
est NULL
.
Par exemple, une colonne de type ENUM("un", "deux", "trois")
peut prendre chacune des valeurs ci-dessous. L'index de la valeur est aussi indiqué.
Value | Index |
NULL | NULL
|
"" | 0 |
"one" | 1 |
"two" | 2 |
"three" | 3 |
Une énumération peut avoir au maximum 65535 éléments.
La casse des lettres est sans importance pour l'affection de valeur dans une colonne de type ENUM
. Cependant, lorsque ces valeurs sont retournées, elles tiennent compte de la casse des lettres tels qu'elle a été spécifiées à la création de la table.
Lire une valeur de type ENUM
dans un contexte numérique permet d'accèder à l'index de la valeur. De même, lors de l'affectation d'un nombre dans une valeur ENUM
, le nombre sera traité comme un index, et la valeur enregistrée sera celle de l'énumération, à l'index précisé.
Les valeurs d'une énumération sont triée en fonction de l'ordre dans lequel les éléments de l'énumération sont enregistrés lors de la création de la colonne (en d'autres termes, les valeurs d'une énumération sont triées en fonction de leur index). Par exemple, "a"
sera placé avant "b"
pour ENUM("a", "b")
, mais "b"
sera placé avant "a"
pour ENUM("b", "a")
.les chaînes vides sont placées avant les chaînes non vides, et la valeur NULL
passe avant toutes les autres.
Pour visualiser toutes les valeurs d'une colonne de type, il faut utiliser SHOW COLUMNS FROM Nom_table LIKE Nom_col_enum
et détailler les valeurs de la deuxième colonne.
SET
Un ensemble est une chaîne qui peut avoir aucune, une ou plusieurs valeurs, chaque valeur étant choisie dans une liste de valeur autorisées lors de la création de la table. Les valeurs de type SET
qui ont plusieurs valeurs sont spécifiées en séparant les membres par des virgules(``,'').. Par conséquent, les valeurs de type SET
ne peuvent pas contenir de virgule.
Par exemple, une colonne de type SET("un", "deux") NOT NULL
peut prendre les valeurs suivantes :
""
"un
"
"deux"
"un, deux"
Un ensemble peut avoir un maximum de 64 membres distincts.
MySQL enregistre les valeurs de type SET
values numériquement, avec le premier élément situé au bit de poids faible. Lorsqu'une valeur de type SET
est retournée dans un contexte numérique, les bits à 1 de cette valeurs correspondent à un membre du SET
qui appartienne à cette valeur. Si un nombre est enregistré dans une valeur de type SET
, alors les bits mis à un de ce nombre détermineront les membres du SET
qui appartiennent à la valeur. Par exemple, une colonne a été spécifiée par SET("a","b","c","d")
.Alors, les membres prennent la valeur suivante :
SET member | Decimal value | Binary value |
a | 1 | 0001
|
b | 2 | 0010
|
c | 4 | 0100
|
d | 8 | 1000
|
Pour les valeurs qui contiennent plus d'un membre, l'ordre d'insertion n'importe pas. Une valeur peut être insérée plusieurs fois, elle n'apparaîtra plus qu'une seule fois dans le SET
, et sera placé dans l'ordre des membres, à la création du SET
. Par exemple, dans une colonne de type SET("a","b","c","d")
, alors les valeurs "a, d"
, "d, a"
et "d,a,a,d,d"
seront devenues "a, d"
, lorsqu'elle seront retournées par la base.
Les valeurs de type s SET
ont triées par ordre numérique. La valeur NULL
est placée avant toutes les autres valeurs non- NULL
.
En général, il est possible d'utiliser la clause SELECT
sur une colonne de type SET
, en utilisant l'opérateur LIKE
ou la fonction FIND_IN_SET()
.
mysql> SELECT * FROM Nom_table WHERE Nom_col LIKE '%valeur%'; mysql> SELECT * FROM Nom_table WHERE FIND_IN_SET(valeur, Nom_col)>0;
Mais les exemples suivants sont aussi corrects
mysql> SELECT * FROM Nom_table WHERE Nom_col = 'val1,val2'; mysql> SELECT * FROM Nom_table WHERE Nom_col & 1;
le premier exemple recherche une valeur exacte ('val1,val2'). Le second exemple recherche les valeurs qui contiennent le premier élément.
Pour visualiser toutes les valeurs d'une colonne de type, il faut utiliser SHOW COLUMNS FROM Nom_table LIKE Nom_col_enum
et détailler les valeurs de la deuxième colonne.
Pour une utilisation aussi efficace de l'espace mémoire, il faut utiliser le type de colonne le plus précis possible. Par exemple, pour stocker un entier dont la valeur va de 1
t 99999
, MEDIUMINT UNSIGNED
est le meilleur type.
La représentation des valeurs monétaires est un problème commun. Avec MySQL, le meilleur choix est le type DECIMAL
. Il est enregistré comme une chaîne, ce qui n'entraîne aucune perte de données. Si la précision n'est pas primordiale, le type DOUBLE
peut être un bon choix.
Pour une meilleure précision, il est toujours possible de convertir les nombres à virgule fixe en BIGINT
. Cela autorise la manipulation d'entier pour les calculs, et il suffit alors de les reconvertir en valeur à virgule flottante au moment de l'affichage.
10.17 Quel sont les différents formats de lignes? Quand utiliser VARCHAR/CHAR
?.
Avec MySQL, tous les types de colonnes peuvent être indexés, à l'exception des types BLOB
et TEXT
. L'utilisation d'index est le meilleur moyen d'accélérer les performances des clauses SELECT
.
Une table peut avoir jusqu'à 16 index. La taille maximale d'un index est de 256 bytes, et cette valeur peut être choisie à la compilation de MySQL.
Il n'est pas possible d'indexer une colonne qui contient des valeurs NULL
, donc une colonne indexée doit être déclarée NOT NULL
.
Pour les colonnes de type CHAR
et VARCHAR
, il est possible de préfixer la colonne. C'est un moyen beaucoup plus rapide et qui requiert moins d'espace disque qu'indexer une colonne complète. La syntaxe pour créer une telle colonne est la suivante :
KEY Nom_index(Nom_col(longueur))
L'exemple suivant créer un index pour les 10 premiers caractères de la colonne Nom_col.
mysql> CREATE TABLE test ( nom CHAR(200) NOT NULL, KEY Nom_index(nom(10)));
MySQL peut créer des indexes sur plusieurs colonnes en même temps. Un index peut contenir jusqu'à 15 colonnes (Avec les colonnes de type CHAR
t VARCHAR
, il est aussi possible d'utiliser un préfixe lors de l'indexation).
Un index de plusieurs colonnes peut être considéré comme un tableau trié contenant les lignes obtenues en concaténant les valeurs des colonnes indexées.
MySQL gère les index sur plusieurs colonnes de manière à ce que les requêtes qui recherche une valeur connue dans la première colonne (avec une clause WHERE
), soient rapides, même si les valeurs pour les autres colonnes ne sont pas précisées.
Par exemple, soit la table suivante :
mysql> CREATE TABLE test ( id INT NOT NULL, nom CHAR(30) NOT NULL, prenom CHAR(30) NOT NULL, PRIMARY KEY (id), INDEX nom_complet (nom, prenom));
Ainsi, l'index nom_complet est un index sur les deux colonnes nom et prénom. L'index sera utilisé lors des requêtes qui recherchent un nom, ou un nom et un prénom. L'index sera donc utilisé lors des requêtes suivantes :
mysql> SELECT * FROM test WHERE nom="Dupont"; mysql> SELECT * FROM test WHERE nom ="Dupont" AND prenom="Michel"; mysql> SELECT * FROM test WHERE nom ="Dupont" AND (prenom ="Michel" OR prenom ="Marie"); mysql> SELECT * FROM test WHERE nom ="Dupont" AND prenom >="M" AND prenom < "N";
Cependant, l'index ne sera pas utilisé lors des requêtes suivantes :
mysql> SELECT * FROM test WHERE prenom ="Michel"; mysql> SELECT * FROM test WHERE nom="Dupont" OR prenom ="Michel";
Afin de simplifier le portage d'applications écrite en SQL sur d'autres base de données, MySQL remplace automatiquement les types présentés ci-dessous par les siens :
Other vendor type | MySQL type |
BINARY(NUM) | CHAR(NUM) BINARY
|
CHAR VARYING(NUM) | VARCHAR(NUM)
|
FLOAT4 | FLOAT
|
FLOAT8 | DOUBLE
|
INT1 | TINYINT
|
INT2 | SMALLINT
|
INT3 | MEDIUMINT
|
INT4 | INT
|
INT8 | BIGINT
|
LONG VARBINARY | MEDIUMBLOB
|
LONG VARCHAR | MEDIUMTEXT
|
MIDDLEINT | MEDIUMINT
|
VARBINARY(NUM) | VARCHAR(NUM) BINARY
|
Ce remplacement intervient à la création de la table. Après la création d'une table, les types retournés par une commande DESCRIBE Nom_table
seront les types équivalent de MySQL.
SELECT
et WHERE
Une clause select
ou where
dans une command SQL peut contenir des expressions utilisant les fonctions décrites ci-dessous.
Une expression qui contient une valeur aura toujours un résultat , sauf exceptions indiquées dans la documentation sur les opérateurs et fonctions.
Note: Il faut nécessairement un espace entre le nom de la fonction et la parenthèse ouvrante qui suit. Cela aide l'analyseur syntaxique de MySQL à faire la différence entre les appels de fonctions et les références aux tables ou colonnes qui interviennent dans la même colonne et qui ont le même nom que la fonction. Les espaces autours des arguments aussi autorisés.
Par souci de brièveté, les affichages d'exemples seront en mode réduit. Par exemple
mysql> select MOD(29,9); 1 rows in set (0.00 sec) +-----------+ | mod(29,9) | +-----------+ | 2 | +-----------+
Sera affiché comme suit :
mysql> select MOD(29,9); -> 2
( ... )
( ... )
mysql> select 1+2*3; -> 7 mysql> select (1+2)*3; -> 9Parentheses. Use these to force the order of evaluation in an expression.
Les opérateurs arithmétiques usuels sont disponible. Il faut bien noter que dans le cas de -
, +
et *
, le resultat est calculé avec la précision BIGINT
(64-bit) si les deux opérateurs sont des entiers.
+
Addition
mysql> select 3+5; -> 8
-
Soustraction
mysql> select 3-5; -> -2
*
Multiplication
mysql> select 3*5; -> 15 mysql> select 18014398509481984*18014398509481984.0; -> 324518553658426726783156020576256.0 mysql> select 18014398509481984*18014398509481984; -> 0
Le résultat du dernier exemple est incorrect, car le résultat de la multiplication excède la taille maximale d'un BIGINT
.
mysql> select 3/5; -> 0.60
La division par zéro retourne une valeur NULL
:
mysql> select 102/(1-1); -> NULL
La division sera calculée avec l'arithmétique des BIGINT
, uniquement dans le cas ou le résultat doit être converti en entier !
MySQL utilise des BIGINT
(64-bit) pour ses opérations sur les bits, donc tous les opérateurs suivants ont au portent au plus 64 bits.
|
OU bit à bit
mysql> select 29 | 15; -> 31
&
ET bit à bit
mysql> select 29 & 15; -> 13
<<
Décalage des bits vers la gauche sur un BIGINT
.
mysql> select 1 << 2 -> 4
>>
Décalage des bits vers la droite sur un BIGINT
.
mysql> select 4 >> 2 -> 1
BIT_COUNT(N)
Compte le nombre de bits mis à un dans l'argument N.
mysql> select BIT_COUNT(29); -> 4
Toutes les opérations logiques retournent 1
(TRUE) ou 0
(FALSE).
NOT
!
NON logique. Retourne 1 si l'argument est 0
, sinon, retourne 0
. Exception: NOT NULL
retourne NULL
.
mysql> select NOT 1; -> 0 mysql> select NOT NULL; -> NULL mysql> select ! (1+1); -> 0 mysql> select ! 1+1; -> 1
Le dernier exemple retourne 1 car l'expression est évaluée de la même façon que (!1)+1
.
OR
||
OU logique. Retourne 1
si l'un des arguments est ni 0
ni NULL
.
mysql> select 1 || 0; -> 1 mysql> select 0 || 0; -> 0 mysql> select 1 || NULL; -> 1
AND
&&
ET logique. Retourne 0
si l'un des arguments est 0
ou NULL
. Sinon, retourne 1.
mysql> select 1 && NULL; -> 0 mysql> select 1 && 0; -> 0
Les opérations de comparaison retourne soit 1
(TRUE), 0
(FALSE) ou NULL
. Ces fonctions s'appliquent aussi bien aux nombres qu'aux chaînes. Les chaînes sont automatiquement converties en nombre et les nombres en chaîne, suivant les besoins (comme en Perl).
MySQL effectue les comparaisons en suivant les règle suivantes
NULL
, le résultat de la comparaison est NULL
.
TIMESTAMP
ou DATETIME
, et l'autre argument est une constante, la constante est convertie au format TIMESTAMP
avant la comparaison. Cette fonction est faite pour assurer la compatibilité ODBC.
Par défaut, les comparaisons de chaîne sont fait sans tenir compte de la casse, et en utilisant le jeu de caractère courant (ISO-8859-1 Latin1 par défaut, qui fonctionne bien pour l'anglais). Les exemples suivants illustrent les règles de conversions lors des opérations de comparaison.
mysql> SELECT 1 > '6x'; -> 0 mysql> SELECT 7 > '6x'; -> 1 mysql> SELECT 0 > 'x6'; -> 0 mysql> SELECT 0 = 'x6'; -> 1
=
Egalité.
mysql> select 1 = 0; -> 0 mysql> select '0' = 0; -> 1 mysql> select '0.0' = 0; -> 1 mysql> select '0.01' = 0; -> 0 mysql> select '.01' = 0.01; -> 1
<>
!=
Différent
mysql> select '.01' <> '0.01'; -> 1 mysql> select .01 <> '0.01'; -> 0 mysql> select 'zorro' <> 'zorrro'; -> 1
<=
Inférieur ou égal
mysql> select 0.1 <= 2; -> 1
<
Strictement inférieur
mysql> select 2 <= 2; -> 1
>=
Supérieur ou égal
mysql> select 2 >= 2; -> 1
>
Strictement supérieur
mysql> select 2 > 2; -> 0
<=>
Egalité : ce opérateur s'assure qu'on ne compare pas NULL et une valeur non nulle.
mysql> select 1 <=> 1, NULL <=> NULL, 1 <=> NULL; -> 1 1 0
expression BETWEEN minimum AND maximum
Si l'expression est comprise entre le minimum et le
maximum
, alors BETWEEN
retourne 1
, sinon 0
. Cette fonction est équivalente à l'expression (minimum <= expression AND expression <= maximum)
si tous les arguments sont du même type. Le premier argument (expression
) détermine la manière dont la comparaison va être faite. Si expression
est une chaîne, la comparaison sera de type chaîne, et insensible à la casse. Si expression
est une chaîne de type binaire, la comparaison sera de type chaîne, et sensible à la casse. Si expression
est un entier, la comparaison sera de type numérique. Si expression
est un nombre à virgule flottante, la comparaison sera de type numérique, à virgule flottante.
mysql> select 1 BETWEEN 2 AND 3; -> 0 mysql> select 'b' BETWEEN 'a' AND 'c'; -> 1 mysql> select 2 BETWEEN 2 AND '3'; -> 1 mysql> select 2 BETWEEN 2 AND 'x-3'; -> 0
expression IN (value,...)
Retourne 1
si expression
est un membre de la liste IN
, sinon retourne 0
.Si toutes les valeurs de la liste IN
sont constantes, alors elles sont toutes converties au type de expression
, et triées. La recherche dans la listes est alors faite avec une recherche binaire. Cela signifie que la recherche est très rapide si la liste IN
ne contient que des constantes. Si expression
est une chaîne sensible à la casse, la comparaison avec les valeurs de IN
en tiendra compte.
mysql> select 2 IN (0,3,5,'wefwf'); -> 0 mysql> select 'wefwf' IN (0,3,5,'wefwf'); -> 1
expression NOT IN (value,...)
Identique à NOT (expression IN (value,...))
.
ISNULL(expression )
Si expression
est NULL
, ISNULL()
retourne 1
, sinon 0
.
mysql> select ISNULL(1+1); -> 0 mysql> select ISNULL(1/0); -> 1
Il faut noter que la comparaison à NULL
avec =
sera toujours fausse!
COALESCE(liste)
Retourne le premier élément non NULL
dans la liste.
mysql> select COALESCE(NULL,1); -> 1 mysql> select ISNULL(NULL,NULL,NULL); -> NULL
INTERVAL(N,N1,N2,N3,...)
Retourne 1
si N1
< N2
< N3
< ...
< Nn
. Si il existe deux valeurs i et j, telles que i < j et Ni > Nj, alors la fonction retourne faux. Toutes les valeurs sont traitées comme des nombres. Cela permet l'utilisation d'une comparaison binaire, très rapide.
mysql> select INTERVAL(23, 1, 15, 17, 30, 44, 200); -> 3 mysql> select INTERVAL(10, 1, 10, 100, 1000); -> 2 mysql> select INTERVAL(22, 23, 30, 44, 200); -> 0
Dans une expression quelconque, si une des chaînes est sensible à la casse, alors la comparaison tiendra compte de la casse.
expr1 LIKE expr2 [ESCAPE 'escape-char']
Expression régulière SQL. Retourne 1
(TRUE) ou 0
(FALSE). Avec LIKE
, les caractères spéciaux suivants sont disponibles :
mysql> select 'David!' LIKE 'David_'; -> 1 mysql> select 'David!' LIKE '%D%v%'; -> 1
Pour tester la présence d'un des caractères spéciaux, il suffit de faire précéder du caractère d'échappement. Si ce dernier n'est pas précisé, le caractère ``\'' est alors utilisé.
mysql> select 'David!' LIKE 'David\_'; -> 0 mysql> select 'David_' LIKE 'David\_'; -> 1
Pour spécifier un autre caractère d'échappement, il faut utiliser la clause ESCAPE
:
mysql> select 'David_' LIKE 'David|_' ESCAPE '|'; -> 1
LIKE
peut travailler avec des expressions numériques (c'est une extension de la norme ANSI SQL.)
mysql> select 10 LIKE '1%'; -> 1
Note: Comme MySQL utilise le système d'échappement du langage C (e.g., ``\n''), il faut doubler toutes les occurrences dans les clause LIKE
. Par exemple, pour rechercher le caractère ``\n'', il faut mettre la chaîne ``\\n''. Pour recherche le caractère for ``\'', il faut l'écrire ``\\\\'' (les backslashes sont supprimés une première fois par l'analyseur syntaxique, et une deuxième fois, quand la recherche est terminée : ce qui laisse un seul backslash à rechercher).
expr1 NOT LIKE expr2 [ESCAPE 'escape-char']
Identique à NOT (expr1 LIKE expr2 [ESCAPE 'escape-char'])
.
expression REGEXP pat
expression RLIKE pat
Effectue une chercher sur la chaîne expression
avec le masque pat
. Le pattern peut être une expression régulière étendue. Retoune 1
si l'expression régulière réussit, 0
. RLIKE
est un synonyme pour REGEXP
, fourni pour assurer la compatibilité avec mSQL Note: Comme MySQL utilise le système d'échappement du langage C (e.g., ``\n''), il faut doubler toutes les occurrences dans les clause. REGEXP
.
mysql> select 'Monty!' REGEXP 'm%y%%'; -> 0 mysql> select 'Monty!' REGEXP '.*'; -> 1 mysql> select 'new*\n*line' REGEXP 'new\\*.\\*line'; -> 1
REGEXP
et RLIKE
utilisent le jeu de caractère (ISO-8859-1 Latin1 par défaut) pour choisir le type de caractère.
expression NOT REGEXP expression
Identique à NOT (expression REGEXP expression )
.
STRCMP(expr1,expr2)
STRCMP()
retourne 0
si les chaînes sont identiques, -1
si le premier argument est plus petit que le second, en fonction de l'ordre de tri courant, et sinon 1
.
mysql> select STRCMP('text', 'text2'); -> -1 mysql> select STRCMP('text2', 'text'); -> 1 mysql> select STRCMP('text', 'text'); -> 0
BINARY
L'opérateur BINARY
transforme la chaîne qui le suive en chaîne insensible à la casse. C'est un moyen simple de forcer une comparaison insensible à la casse, même si la colonne n'a pas été définie comme un BINARY
ou BLOB
.
mysql> select "a" = "A"; -> 1 mysql> select BINARY "a" = "A"; -> 0
BINARY
a été introduit dans MySQL 3.23.0
IFNULL(expr1,expr2)
Si expr1
n'est pas NULL
, IFNULL()
retourne expr1
, sinon expr2
. IFNULL()
retourne un nombre ou une chaîne, en fonction du contexte dans lequel il est utilisé.
mysql> select IFNULL(1,0); -> 1 mysql> select IFNULL(0,10); -> 0 mysql> select IFNULL(1/0,10); -> 10 mysql> select IFNULL(1/0,'yes'); -> 'yes'
IF(expr1,expr2,expr3)
Si expr1
est vraie (TRUE) (expr1 <> 0
et expr1 <> NULL
) alors IF()
retourne expr2
, sinon il retourne expr3
. IF()
retourne un nombre ou une chaîne, en fonction du contexte dans lequel il est utilisé.
mysql> select IF(1>2,2,3); -> 3 mysql> select IF(1<2,'yes','no'); -> 'yes' mysql> select IF(strcmp('test','test1'),'yes','no'); -> 'no'
expr1
est évaluée en tant qu'entier, ce qui signifie que si le test portait sur un nombre à virgule flottante ou une chaîne, il faudrait mieux utiliser un opérateur de comparaison.
mysql> select IF(0.1,1,0); -> 0 mysql> select IF(0.1<>0,1,0); -> 1
Dans le premier cas ci-dessus, IF(0.1)
retourne 0
car 0.1
est converti en un nombre entier, ce qui conduit à un test de type IF(0)
. C'est une source d'erreur. Dans le deuxième cas, la comparaison est faite avec un opérateur de comparaison, qui teste la non nullité. Le résultat de la comparaison est utilisé comme un entier.
result
si value=compare-value
.
La seconde version retourne le résultat si la première condition est vraie. Si il n'y a aucun résultat, alors, le résultat après ELSE
est retourné. SI il n'y a pas de résultat pour ELSE
alors NULL
.
mysql> SELECT CASE 1 WHEN 1 THEN "un" WHEN 2 THEN "deux" ELSE "plus" END; -> "un" mysql> SELECT CASE WHEN 1>0 THEN "vrai" ELSE "faux" END; -> "vrai" mysql> SELECT CASE BINARY "B" when "a" then 1 when "b" then 2 END; -> NULL
Toutes les fonctions mathématiques retourne NULL
en cas d'erreur.
-
Moins unaire. Change le signe de l'argument.
mysql> select - 2; -> -2
Note : si cet opérateur est utilisé avec un BIGINT
, le résultat sera BIGINT
! Cela signifie qu'il faut éviter d'utiliser –
sur des entiers qui ont la valeur -2^63
!
ABS(X)
Valeur absolue de X
.
mysql> select ABS(2); -> 2 mysql> select ABS(-32); -> 32
Cette fonction ne pose aucun problème particulier avec les valeurs de type BIGINT
.
SIGN(X)
Retourne le signe de l'argument sous la forme -1
, 0
or 1
, suivant que X
est négatif, nul, ou positif.
mysql> select SIGN(-32); -> -1 mysql> select SIGN(0); -> 0 mysql> select SIGN(234); -> 1
MOD(N,M)
%
Modulo (identique à l'opérateur %
en langage C). Retourne le reste de la division euclidienne de N
par M
.
mysql> select MOD(234, 10); -> 4 mysql> select 253 % 7; -> 1 mysql> select MOD(29,9); -> 2
Cette fonction ne pose aucun problème particulier avec les valeurs de type BIGINT
.
FLOOR(X)
Retourne le plus grand entier possible mais plus petit que X
.
mysql> select FLOOR(1.23); -> 1 mysql> select FLOOR(-1.23); -> -2
Note : le résultat est converti en BIGINT
!
CEILING(X)
Retourne le plus petit entier possible mais plus grand que X
.
mysql> select CEILING(1.23); -> 2 mysql> select CEILING(-1.23); -> -1
Note : le résultat est converti en BIGINT
!
ROUND(X)
Retourne l'argument X
, arrondi à l'entier le plus proche.
mysql> select ROUND(-1.23); -> -1 mysql> select ROUND(-1.58); -> -2 mysql> select ROUND(1.58); -> 2
Note : le résultat est converti en BIGINT
!
ROUND(X,D)
Retourne l'argument X
, arrondi au décimal le plus proche, avec D
décimales. Si D
=0, le résultat n'aura pas de partie décimale.
mysql> select ROUND(1.298, 1); -> 1.3 mysql> select ROUND(1.298, 0); -> 1
Note : le résultat est converti en BIGINT!
EXP(X)
Retourne la valeur de e
(base des logarithmes naturels ou népériens) à la puissance X
.
mysql> select EXP(2); -> 7.389056 mysql> select EXP(-2); -> 0.135335
LOG(X)
Retourne le logarithme naturel de X
.
mysql> select LOG(2); -> 0.693147 mysql> select LOG(-2); -> NULL
Pour obtenir la valeur du logarithme de X
dans une base arbitraire, il faut utiliser la formule LOG(X)/LOG(B)
.
LOG10(X)
Retourne le logarithme de X
en base 10.
mysql> select LOG10(2); -> 0.301030 mysql> select LOG10(100); -> 2.000000 mysql> select LOG10(-100); -> NULL
POW(X,Y)
POWER(X,Y)
Retourne la valeur de X
à la puissance Y
.
mysql> select POW(2,2); -> 4.000000 mysql> select POW(2,-2); -> 0.250000
SQRT(X)
Retourne la racine carrée positive de X
.
mysql> select SQRT(4); -> 2.000000 mysql> select SQRT(20); -> 4.472136
PI()
Retourne la valeur de PI.
mysql> select PI(); -> 3.141593
COS(X)
Retourne le cosinus de X
, avec X
en radians.
mysql> select COS(PI()); -> -1.000000
SIN(X)
Retourne le sinus de X
, avec X
en radians.
mysql> select SIN(PI()); -> 0.000000
TAN(X)
Retourne la tangente de X
, avec X
en radians.
mysql> select TAN(PI()+1); -> 1.557408
ACOS(X)
Retourne l'arcosinus de X
, c'est à dire l'angle dont le cosinus est X
en radians. Retourne NULL
si X
n'est pas compris entre -1
et 1
.
mysql> select ACOS(1); -> 0.000000 mysql> select ACOS(1.0001); -> NULL mysql> select ACOS(0); -> 1.570796
ASIN(X)
Retourne l'arsinus de X
, c'est à dire l'angle dont le sinus est X
en radians. Retourne NULL
si X
n'est pas compris entre -1
et 1
.
mysql> select ASIN(0.2); -> 0.201358 mysql> select ASIN('foo'); -> 0.000000
ATAN(X)
Retourne l'arctangente de X
, c'est à dire l'angle dont la tangente est X
en radians.
mysql> select ATAN(2); -> 1.107149 mysql> select ATAN(-2); -> -1.107149
ATAN2(X,Y)
Retourne l'arc tangente de deux variables X
et Y
. C'est le même calcul que arc tangent of Y / X
, hormis le fait que les signes des deux arguments est utilisé pour déterminer le quadrant du résultat.
mysql> select ATAN(-2,2); -> -0.785398 mysql> select ATAN(PI(),0); -> 1.570796
COT(X)
Retourne la cotangente de X
.
mysql> select COT(12); -> -1.57267341 mysql> select COT(0); -> NULL
RAND()
RAND(N)
Retourne un nombre aléatoire, compris entre 0
et 1.0
. Si un entier N
est précisé, il est utilisé comme valeur de seed.
mysql> select RAND(); -> 0.5925 mysql> select RAND(20); -> 0.1811 mysql> select RAND(20); -> 0.1811 mysql> select RAND(); -> 0.2079 mysql> select RAND(); -> 0.7888
Il est impossible d'utiliser une colonne de valeur RAND()
avec la clause ORDER BY
, car la colonne sera évalué plusieurs fois. Avec MySQL 3.23, il est cependant possible d'écrire: SELECT * FROM Nom_table ORDER BY RAND()
. Comme cela, il est possible de faire une sélection aléatoire d'une table : SELECT * FROM table1,table2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000
.
LEAST(X,Y,...)
Au moins deux arguments, retourne la plus petite valeur (minimum). Les arguments sont comparés en utilisant les règles suivantes :
LEAST
est utilisé dans un contexte d'entiers, ou bien tous les arguments sont des entiers, les arguments sont évalués et comparés en tant qu'entiers.
LEAST
est utilisé dans un contexte de nombre à virgule flottante, les arguments sont évalués et comparés en tant que nombre à virgule flottante.
mysql> select LEAST(2,0); -> 0 mysql> select LEAST(34.0,3.0,5.0,767.0); -> 3.0 mysql> select LEAST("B","A","C"); -> "A"
Avec les version de MySQL antérieur à la 3.22.5, il est possible d'utiliser MIN()
à la place de LEAST
.
GREATEST(X,Y,...)
Retourne le plus grand argument de la liste. Les arguments sont comparés de la même manière que pour LEAST
.
mysql> select GREATEST(2,0); -> 2 mysql> select GREATEST(34.0,3.0,5.0,767.0); -> 767.0 mysql> select GREATEST("B","A","C"); -> "C"
Avec les version de MySQL antérieur à la 3.22.5, il est possible d'utiliser MAX ()
à la place de GREATEST
.
DEGREES(X)
Retourne l'argument X
, converti de radians en degrés.
mysql> select DEGREES(PI()); -> 180.000000
RADIANS(X)
Retourne l'argument X
, converti de radians degrés en radians.
mysql> select RADIANS(90); -> 1.570796
TRUNCATE(X,D)
Retourne l'argument X
, tronqué à D
décimales.
mysql> select TRUNCATE(1.223,1); -> 1.2 mysql> select TRUNCATE(1.999,1); -> 1.9 mysql> select TRUNCATE(1.999,0); -> 1
Les fonctions qui retourne des chaînes, retourneront NULL
si le résultat dépasse la taille maximale de max_allowed_packet
.
Pour les opérations sur les chaînes, le premier caractère est en position 1.
ASCII(str)
Retourne le code ASCII du premier caractère de la chaîne. Si la chaîne est vide, retourne 0
. Si la chaîne est NULL
, retourne NULL
.
mysql> select ASCII('2'); -> 50 mysql> select ASCII(2); -> 50 mysql> select ASCII('dx'); -> 100
CONV(N,from_base,to_base)
Converti des nombres d'une base à l'autre, et retourne la chaîne représentant le résultat converti. Si la chaîne est NULL
, retourne NULL
. L'argument N
est considéré comme un entier, mais peut être un entier ou une chaîne. La base minimum est 2, et maximum est 36. Si la base d'arrivée est un nombre négatif, N
est considéré comme un entier signé. Sinon, N
est traité comme un entiers non signé. CONV
fonctionne à la précision 64 bits.
mysql> select CONV("a",16,2); -> '1010' mysql> select CONV("6E",18,8); -> '172' mysql> select CONV(-17,10,-18); -> '-H' mysql> select CONV(10+"10"+'10'+0xa,10,10); -> '40'
BIN(N)
Retourne une chaîne représentant l'argument N
en binaire. N
est un BIGINT
. Cette fonction est l'équivalent de CONV(N,10,2)
. Retourne NULL
si N
est NULL
.
mysql> select BIN(12); -> '1100'
OCT(N)
Retourne une chaîne représentant l'argument N
en base 8. N
est un BIGINT
. Cette fonction est l'équivalent de CONV(N,10,8)
. Retourne NULL
si N
est NULL
.
mysql> select OCT(12); -> '14'
HEX(N)
Retourne une chaîne représentant l'argument N
en hexadécimal. N
est un BIGINT
. Cette fonction est l'équivalent de CONV(N,10,16)
. Retourne NULL
si N
est NULL
.
mysql> select HEX(255); -> 'FF'
CHAR(N,...)
Interprète les arguments comme des nombres entiers, et retourne une chaîne constituée des caractères correspondant aux codes ASCII des arguments. Les valeurs NULL
sont ignorées.
mysql> select CHAR(77,121,83,81,'76'); -> 'MySQL' mysql> select CHAR(77,77.3,'77.3'); -> 'MMM'
CONCAT(X,Y,...)
Concatène les arguments, et re tourne le résultat. Retourne NULL
si un des arguments est NULL
. Le nombre d'argument minimum est 2.
mysql> select CONCAT('My', 'S', 'QL'); -> 'MySQL' mysql> select CONCAT('My', NULL, 'QL'); -> NULL
LONGUEUR(str)
OCTET_LONGUEUR(str)
CHAR_LONGUEUR(str)
CHARACTER_LONGUEUR(str)
Retourne la longueur de la chaîne str
.
mysql> select LONGUEUR('text'); -> 4 mysql> select OCTET_LONGUEUR('text'); -> 4
LOCATE(substr,str)
POSITION(substr IN str)
Retourne la position de la première occurrence de substr
dans la chaîne. Retourne 0
si substr
n'est pas trouvée.
mysql> select LOCATE('bar', 'foobarbar'); -> 4 mysql> select LOCATE('xbar', 'foobar'); -> 0
LOCATE(substr,str,pos)
Retourne la position de la première occurrence de substr
dans la chaîne, en commencant à chercher à partir de la position pos
. Retourne 0
si substr
n'est pas trouvée.
mysql> select LOCATE('bar', 'foobarbar',5); -> 7
INSTR(str,substr)
Retourne la position de la première occurrence de substr
dans la chaîne, en commencant à chercher à partir de la position pos
. Retourne 0
si substr
n'est pas trouvée. C'est la même fonction que LOCATE()
, mais les deux arguments n'ont pas la même place.
mysql> select INSTR('foobarbar', 'bar'); -> 4 mysql> select INSTR('xbar', 'foobar'); -> 0
LPAD(str,len,padstr)
Retourne la chaîne str
, complétée à gauche par la chaîne padstr
jusqu'à ce que le résultat ait la longueur .
mysql> select LPAD('hi',4,'??'); -> '??hi'
RPAD(str,len,padstr)
Retourne la chaîne str
, complétée à droite par la chaîne padstr
jusqu'à ce que le résultat ait la longueur .
mysql> select RPAD('hi',5,'?'); -> 'hi???'
LEFT(str,len)
Retourne les len
premiers caractères de la chaîne str
.
mysql> select LEFT('foobarbar', 5); -> 'fooba'
RIGHT(str,len)
SUBSTRING(str FROM len)
Retourne les len
derniers caractères de la chaîne str
.
mysql> select RIGHT('foobarbar', 4); -> 'rbar' mysql> select SUBSTRING('foobarbar' FROM 4); -> 'rbar'
SUBSTRING(str,pos,len)
SUBSTRING(str FROM pos FOR len)
MID(str,pos,len)
Retourne les len
caractères de la chaîne str, en commencant à partir de la position pos
. La variante FROM
est une syntaxe issue de la norme ANSI SQL92.
mysql> select SUBSTRING('Quadratically',5,6); -> 'ratica'
SUBSTRING(str,pos)
Retourne une sous-chaîne, issue de str
et commencant à la position pos
.
mysql> select SUBSTRING('Quadratically',5); -> 'ratically'
SUBSTRING_INDEX(str,delim,count)
Retourne une sous-chaîne, issue de str
, après count
occurrences du délimiteur delim
. Si count
est positif, la sous-chaîne comprendra tous les caractères situés à gauche du délimiteur final. Si count
est négatif, la sous-chaîne comprendra tous les caractères situés à droite du délimiteur final
mysql> select SUBSTRING_INDEX('www.mysql.com', '.', 2); -> 'www.mysql' mysql> select SUBSTRING_INDEX('www.mysql.com', '.', -2); -> 'mysql.com'
LTRIM(str)
Retourne la chaîne str
après élimination des espaces situés en début de chaîne.
mysql> select LTRIM(' barbar'); -> 'barbar'
RTRIM(str)
retourne la chaîne str
après élimination des espaces situés en fin de chaîne.
mysql> select RTRIM('barbar '); -> 'barbar'
TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)
Retourne la chaîne str
après élimination de chaînes remstr
situées en début et/ou fin de chaîne. Si aucune des options BOTH
, LEADING
ou TRAILING
n'est précisé, alors BOTH
est utilisé par défaut. Si remstr
n'est pas précisé, les espaces sont éliminés.
mysql> select TRIM(' bar '); -> 'bar' mysql> select TRIM(LEADING 'x' FROM 'xxxbarxxx'); -> 'barxxx' mysql> select TRIM(BOTH 'x' FROM 'xxxbarxxx'); -> 'bar' mysql> select TRIM(TRAILING 'xyz' FROM 'barxxyz'); -> 'barx'
SOUNDEX(str)
Retourne une représentation phonétique de la chaîne . Deux chaînes qui " sonne de la même façon " devraient avoir des représentation identiques. Une représentation standard a 4 caractères, mais SOUNDEX()
retourne un nombre arbitraire de caractère. Il faudra alors utiliser SUBSTRING()
sur le résultat pour avoir une représentation standard. Les caractères non-alphanumériques sont ignorés. Tous les caractères alphabétiques hors de l'intervalle A-Z sont considéré comme des voyelles.
mysql> select SOUNDEX('Hello'); -> 'H400' mysql> select SOUNDEX('Quadratically'); -> 'Q36324'
SPACE(N)
Crée une chaîne contenant N
espaces.
mysql> select SPACE(6); -> ' '
REPLACE(str,from_str,to_str)
Remplace les occurrences de from_str
par la chaîne to_str
, dans la chaîne str
.
mysql> select REPLACE('www.mysql.com', 'w', 'Ww'); -> 'WwWwww.mysql.com'
REPEAT(str,count)
Retourne une chaîne constituée des répétitions de la chaîne . Si count <= 0
, retourne une chaîne vide. Si str
ou count
est NULL
, retourne NULL
.
mysql> select REPEAT('MySQL', 3); -> 'MySQLMySQLMySQL'
REVERSE(str)
Inverse l'ordre des caractères de la chaîne str
.
mysql> select REVERSE('abc'); -> 'cba'
INSERT(str,pos,len,newstr)
Retourne la chaîne str
, avec la chaîne newstr
qui remplace tous les caractères à partir de la position pos
, et sur la longueur len
.
mysql> select INSERT('Quadratic', 3, 4, 'What'); -> 'QuWhattic'
ELT(N,str1,str2,str3,...)
Retourne str1
si N
= 1
, str2
si N
= 2
, etc... Retourne NULL
si est plus petit que 1
ou plus grand que le nombre d'arguments. ELT()
est le contraire de FIELD()
.
mysql> select ELT(1, 'ej', 'Heja', 'hej', 'foo'); -> 'ej' mysql> select ELT(4, 'ej', 'Heja', 'hej', 'foo'); -> 'foo'
FIELD(str,str1,str2,str3,...)
Retourne l'index de la chaîne str
dans la liste des arguments . Retourne 0
si str
n'est pas trouvé .FIELD()
est le contraire de ELT()
mysql> select FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo'); -> 2 mysql> select FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo'); -> 0
FIND_IN_SET(str,strlist)
Retourne l'index de la chaîne dans la liste. Une liste de chaîne est composée de chaînes, séparées par le caractère ``,''. Si le premier argument est une chaîne constante, et le deuxième est une colonne de type SET
, la fonction est optimisée FIND_IN_SET()
pour utiliser l'arithmétique sur les bits ! Retourne str
si n'est pas dans la liste strlist
, ou si la liste est vide. Retourne NULL
si l'un des arguments est NULL
. La fonction n'accepte pas de caractère ``,''dans le premier membre de la liste.
mysql> SELECT FIND_IN_SET('b','a,b,c,d'); -> 2
MAKE_SET(bits,str1,str2,...)
Retourne un ensemble (une chaîne contenant des sous-chaînes séparée par ``,'') qui correspond à u sous-ensemble des chaînes en arguments. La chaîne à l'index i sera présente dans l'ensemble résultat, si le bit à l'index i est à un, dans bits).
mysql> SELECT MAKE_SET(1,'a','b','c'); -> 'a' mysql> SELECT MAKE_SET(1 | 4,'hello','nice','world'); -> 'hello,world' mysql> SELECT MAKE_SET(0,'a','b','c'); -> ''
EXPORT_SET(bits,on,off,[separator],[number_of_bits])
Retourne une chaîne dans laquelle, pour chaque bit à 1 , il y a la chaîne on
, pour chaque bit à 0 , il y a la chaîne off
, séparés par le separator
(par défaut, ','), et uniquement pour les number_of_bits
(par défaut, 64) premiers bits.
mysql> select EXPORT_SET(5,'Y','N',',',4) -> Y,N,Y,N
LCASE(str)
LOWER(str)
Retourne la chaîne avec tous les caractères en minuscules, conformément au jeu de caractère courant (par défaut, ISO-8859-1 Latin1).
mysql> select LCASE('QUADRATICALLY'); -> 'quadratically'
UCASE(str)
UPPER(str)
Retourne la chaîne avec tous les caractères en majuscule, conformément au jeu de caractère courant (par défaut, ISO-8859-1 Latin1).
mysql> select UCASE('Hej'); -> 'HEJ'
LOAD_FILE(Nom_fichier)
Lit le fichier Nom_fichier
et retourne le résultat dans une chaîne. Le fichier doit être sur le serveur, et il faut préciser le nom et le chemin d'accès complet. Le fichier doit être lisible par tous, et être plus petit que max_allowed_packet
. Si le fichier n'existe pas, ou ne peut être lu, la fonction retourne NULL
.
mysql> UPDATE Nom_tableSET blob_column=LOAD_FILE("/tmp/picture") WHERE id=1;
Il n'y a pas de fonction de conversion d'un nombre en char. Il n'y en pas besoin, car MySQL converti automatiquement les nombres en chaînes, et vice versa.
mysql> SELECT 1+"1"; -> 2 mysql> SELECT CONCAT(2,' test'); -> '2 test'
Si une fonction qui travaille sur des chaînes sensibles à la casse recoit comme argument une chaîne insensible à la casse, le resultat sera aussi une chaîne insensible à la casse. Un nombre converti en chaîne est traité comme une chaîne insensible à la casse. Cela n'affecte que les comparaisons.
7.2.6 Types date et heure pour une description précise des intervalles de validité de chaque type.
Voici un exemple qui utilise des fonctions sur les dates et heures. La requête ci-dessous sélectionne toutes les lignes avec une valeur qui est date_col
dans les 30 derniers jours :
mysql> SELECT quelquechose FROM table WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;
DAYOFWEEK(date)
Retourne le jour de la semaine sous la forme d'un index qui commence à 1 (1
= Dimanche, 2
= Lundi, ... 7
= Samedi). Ces valeurs sont celles du standard ODBC.
mysql> select DAYOFWEEK('1998-02-03'); -> 3
WEEKDAY(date)
Retourne le jour de la semaine sous la forme d'un index qui commence à 0 (0
= Dimanche, 1
= Lundi, ... 6
= Samedi).
mysql> select WEEKDAY('1997-10-04 22:23:00'); -> 5 mysql> select WEEKDAY('1997-11-05'); -> 2
DAYOFMONTH(date)
Retourne le jour du mois sous la forme d'un index entre 1
et 31
.
mysql> select DAYOFMONTH('1998-02-03'); -> 3
DAYOFYEAR(date)
Retourne le jour de l'année sous la forme d'un index entre 1
et 366
.
mysql> select DAYOFYEAR('1998-02-03'); -> 34
MONTH(date)
Retourne le mois de la date
sous la forme d'un index entre 1
et 12
.
mysql> select MONTH('1998-02-03'); -> 2
DAYNAME(date)
Retourne le nom du jour de la date
sous la forme d'une chaîne (en anglais ).
mysql> select DAYNAME("1998-02-05"); -> 'Thursday'
MONTHNAME(date)
Retourne le nom du mois de la date
sous la forme d'une chaîne (en anglais ).
mysql> select MONTHNAME("1998-02-05"); -> 'February'
QUARTER(date)
Retourne le trimestre de la date
sous la forme d'un index entre 1
et 4
.
mysql> select QUARTER('98-04-01'); -> 2
WEEK(date)
WEEK(date,first)
Avec un seul argument, retourne la semaine de la date
sous la forme d'un index entre 1
à 52
, avec Dimanche comme premier jour de la semaine. La fonction avec deux arguments permet de préciser si la semaine commence à Dimanche (0
) ou Lundi (1
).
mysql> select WEEK('1998-02-20'); -> 7 mysql> select WEEK('1998-02-20',0); -> 7 mysql> select WEEK('1998-02-20',1); -> 8
YEAR(date)
Retourne l'année de la date
sous la forme d'un index entre 1000
et 9999
.
mysql> select YEAR('98-02-03'); -> 1998
HOUR(time)
Retourne l'heure de la date
sous la forme d'un index entre 0
et 23
.
mysql> select HOUR('10:05:03'); -> 10
MINUTE(time)
Retourne la minute de la date
sous la forme d'un index entre 0
et 59
.
mysql> select MINUTE('98-02-03 10:05:03'); -> 5
SECOND(time)
Retourne la seconde de la date
sous la forme d'un index entre 0
et 59
.
mysql> select SECOND('10:05:03'); -> 3
PERIOD_ADD(P,N)
Ajoute N
mois à la date P
(au format YYMM
ou YYYYMM
). Retourne le résultat au format YYYYMM
. Il faut bien noter que la date P
n'est pas au format date
.
mysql> select PERIOD_ADD(9801,2); -> 199803
PERIOD_DIFF(P1,P2)
Retourne le nombre de mois entre deux dates P1
et P2
. P1
et P2
doivent être au format . Il faut bien noter que les dates P1
et P2
ne sont pas au format date
.
mysql> select PERIOD_DIFF(9802,199703); -> 11
DATE_ADD(date,INTERVAL expression type)
DATE_SUB(date,INTERVAL expression type)
ADDDATE(date,INTERVAL expression type)
SUBDATE(date,INTERVAL expression type)
Ces fonctions effectuent des opérations arithmétiques sur les dates. Elles ont été inserées dans MySQL 3.22. ADDDATE()
et SUBDATE()
sont synonymes de DATE_ADD()
et DATE_SUB()
. date
est de type DATETIME
ou DATE
, qui indique la date de début. expression
est une expression qui donne une durée à ajouter ou à retrancher à la date de début. expression
est une chaîne qui peut commencer par un signe moins (``-''), pour indiquer une durée négative. type
est un mot clé qui indique comment l'expression doit être considéré. La table suivante établit la relation type
et expression
:
type value | Meaning | Expected expr format
|
SECOND | Seconds | SECONDS
|
MINUTE | Minutes | MINUTES
|
HOUR | Hours | HOURS
|
DAY | Days | DAYS
|
MONTH | Months | MONTHS
|
YEAR | Years | YEARS
|
MINUTE_SECOND | Minutes and seconds | "MINUTES:SECONDS"
|
HOUR_MINUTE | Hours and minutes | "HOURS:MINUTES"
|
DAY_HOUR | Days and hours | "DAYS HOURS"
|
YEAR_MONTH | Years and months | "YEARS-MONTHS"
|
HOUR_SECOND | Hours, minutes, | "HOURS:MINUTES:SECONDS"
|
DAY_MINUTE | Days, hours, minutes | "DAYS HOURS:MINUTES"
|
DAY_SECOND | Days, hours, minutes, seconds | "DAYS HOURS:MINUTES:SECONDS"
|
expr
format.
The ones shown in the table are the suggested delimiters. If the date
argument is a DATE
value and your calculations involve only
YEAR
, MONTH
and DAY
parts (that is, no time parts), the
result is a DATE
value. Otherwise the result is a DATETIME
value.
mysql> SELECT DATE_ADD("1997-12-31 23:59:59", INTERVAL 1 SECOND); -> 1998-01-01 00:00:00 mysql> SELECT DATE_ADD("1997-12-31 23:59:59", INTERVAL 1 DAY); -> 1998-01-01 23:59:59 mysql> SELECT DATE_ADD("1997-12-31 23:59:59", INTERVAL "1:1" MINUTE_SECOND); -> 1998-01-01 00:01:00 mysql> SELECT DATE_SUB("1998-01-01 00:00:00", INTERVAL "1 1:1:1" DAY_SECOND); -> 1997-12-30 22:58:59 mysql> SELECT DATE_ADD("1998-01-01 00:00:00", INTERVAL "-1 10" DAY_HOUR); -> 1997-12-30 14:00:00 mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY); -> 1997-12-02 mysql> SELECT EXTRACT(YEAR FROM "1999-07-02"); -> 1999 mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03"); -> 199907 mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03"); -> 20102MySQL accepte l'utilisation de délimiteurs non-numériques dans le format de
expression
. Ceux présentés dans le tableaux ne sont que des suggestions. Si l'argument date
est au format DATE
et que les calculs font intervenir seulement YEAR
, MONTH
et DAY
(c'est à dire, juste la date, par l'heure.), le résultat est de type DATE
. Sinon, le résultat des de type DATETIME
.
mysql> select DATE_ADD("1997-12-31 23:59:59", INTERVAL 1 SECOND); -> 1998-01-01 00:00:00 mysql> select DATE_ADD("1997-12-31 23:59:59", INTERVAL 1 DAY); -> 1998-01-01 23:59:59 mysql> select DATE_ADD("1997-12-31 23:59:59", INTERVAL "1:1" MINUTE_SECOND); -> 1998-01-01 00:01:00 mysql> select DATE_SUB("1998-01-01 00:00:00", INTERVAL "1 1:1:1" DAY_SECOND); -> 1997-12-30 22:58:59 mysql> select DATE_ADD("1998-01-01 00:00:00", INTERVAL "-1 10" DAY_HOUR); -> 1997-12-30 14:00:00 mysql> select DATE_SUB("1998-01-02", INTERVAL 31 DAY); -> 1997-12-02
Si l'argument de durée est trop court par rapport au mot clé spécifié, MySQL suppose que les parties de gauche sont mises à zéro. Par exemple, avec le mot clé DAY_SECOND
, s'attend à trouver le format "JOURS HEURES:MINUTES:SECONDES"
. Si l'argument de durée est "1:10"
, supposera que les jours et heures sont à 0, et que seules, les minutes et secondes sont fournies. En un sens, MySQL ignore le type spécifié, et utilise à la place MINUTE_SECOND
. Si les dates sont incorrectes, le résultat est NULL
. Par ailleurs, lors de l'utilisation des options MONTH
, YEAR_MONTH
ou YEAR
, et que dans le mois résultant, la date du jours n'existe pas, elle est automatiquement ramenée à la plus grande valeur qu'elle peut prendre dans ce mois.
mysql> select DATE_ADD('1998-01-30', Interval 1 month); -> 1998-02-28
Note from the preceding example that the word INTERVAL
and the type
keyword are not case sensitive.
TO_DAYS(date)
Retourne l'index du jour par rapport au 1er janvier 0.
mysql> select TO_DAYS(950501); -> 728779 mysql> select TO_DAYS('1997-10-07'); -> 729669
TO_DAYS()
n'est pas prévu pour utiliser des dates précédents l'avènement du calendrier Grégorien. (1582)..
FROM_DAYS(N)
Etant donné un numéro de jour par rapport au 1er janvier 0, retourne une valeur de type DATE
.
mysql> select FROM_DAYS(729669); -> '1997-10-07'
FROM_DAYS()
n'est pas prévu pour utiliser des dates précédents l'avènement du calendrier Grégorien. (1582).
DATE_FORMAT(date,format)
Formate la date date
en fonction de la chaîne format
. Les formats suivants peuvent être utilisé dans format
:
%M | Month name (January ..December )
|
%W | Weekday name (Sunday ..Saturday )
|
%D | Day of the month with english suffix (1st , 2nd , 3rd , etc.)
|
%Y | Year, numeric, 4 digits |
%y | Year, numeric, 2 digits |
%a | Abbreviated weekday name (Sun ..Sat )
|
%d | Day of the month, numeric (00 ..31 )
|
%e | Day of the month, numeric (0 ..31 )
|
%m | Month, numeric (01 ..12 )
|
%c | Month, numeric (1 ..12 )
|
%b | Abbreviated month name (Jan ..Dec )
|
%j | Day of year (001 ..366 )
|
%H | Hour (00 ..23 )
|
%k | Hour (0 ..23 )
|
%h | Hour (01 ..12 )
|
%I | Hour (01 ..12 )
|
%l | Hour (1 ..12 )
|
%i | Minutes, numeric (00 ..59 )
|
%r | Time, 12-hour (hh:mm:ss [AP]M )
|
%T | Time, 24-hour (hh:mm:ss )
|
%S | Seconds (00 ..59 )
|
%s | Seconds (00 ..59 )
|
%p | AM or PM
|
%w | Day of the week (0 =Sunday..6 =Saturday)
|
%U | Week (0 ..52 ), where Sunday is the first day of the week
|
%u | Week (0 ..52 ), where Monday is the first day of the week
|
%% | A literal `%'. |
mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y'); -> 'Saturday October 1997' mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s'); -> '22:23:00' mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%D %y %a %d %m %b %j'); -> '4th 97 Sat 04 10 Oct 277' mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H %k %I %r %T %S %w'); -> '22 22 10 10:23:00 PM 22:23:00 00 6'
Depuis MySQL 3.23, le caractère %
est obligatoire devant le caractère de format. Dans les versions antérieures de MySQL, %
il était optionnel.
TIME_FORMAT(time,format)
Utilisation identique à DATE_FORMAT()
, mais seulement pour les heures (heures, minutes secondes). Les autres arguments conduisent à un résultat a NULL
ou 0
.
CURDATE()
CURRENT_DATE
Retourne la date du jour, au format 'YYYY-MM-DD'
ou YYYYMMDD
, suivant que la fonction est utilisée en contexte chaîne ou numérique
mysql> select CURDATE(); -> '1997-12-15' mysql> select CURDATE() + 0; -> 19971215
CURTIME()
CURRENT_TIME
Retourne l'heure du jour, au format 'HH:MM:SS'
or HHMMSS
, suivant que la fonction est utilisée en contexte chaîne ou numérique
mysql> select CURTIME(); -> '23:50:26' mysql> select CURTIME() + 0; -> 235026
NOW()
SYSDATE()
CURRENT_TIMESTAMP
Retourne la date et l'heure du jour, au format 'YYYY-MM-DD HH:MM:SS'
or YYYYMMDDHHMMSS
, suivant que la fonction est utilisée en contexte chaîne ou numérique
mysql> select NOW(); -> '1997-12-15 23:50:26' mysql> select NOW() + 0; -> 19971215235026
UNIX_TIMESTAMP()
UNIX_TIMESTAMP(date)
Utilisé sans argument, retourne un timestamp Unix (le nombre de secondes depuis '1970-01-01 00:00:00'
GMT) . Utilisé avec un argument de type date
, il renvoie le timestamp Unix correspondant à cette date. DATE
peut être aux formats chaîne DATE
chaîne, DATETIME
chaîne, TIMESTAMP
, ou un nombre au format YYMMDD
ou YYYYMMDD
.
mysql> select UNIX_TIMESTAMP(); -> 882226357 mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00'); -> 875996580
Quand un UNIX_TIMESTAMP
est affecté à une colonne de type TIMESTAMP
, l'affectation sera directe, avec aucune conversion implicite.
unix_timestamp
au format 'YYYY-MM-DD HH:MM:SS'
or YYYYMMDDHHMMSS
suivant que la fonction est utilisée en contexte chaîne ou numérique
mysql> select FROM_UNIXTIME(875996580); -> '1997-10-04 22:23:00' mysql> select FROM_UNIXTIME(875996580) + 0; -> 19971004222300
FROM_UNIXTIME(unix_timestamp,format)
Retourne la représentation de l'argument unix_timestamp
au format format
, suivant que la fonction est utilisée en contexte chaîne ou numérique. Le format est spécifié comme pour la fonction the DATE_FORMAT().
mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x'); -> '1997 23rd December 03:43:30 x'
SEC_TO_TIME(seconds)
Converti l'argument seconds
en heures, minutes et secondes, au format 'HH:MM:SS'
or HHMMSS
, suivant que la fonction est utilisée en contexte chaîne ou numérique
mysql> select SEC_TO_TIME(2378); -> '00:39:38' mysql> select SEC_TO_TIME(2378) + 0; -> 3938
TIME_TO_SEC(time)
Retourne l'argument time
, converti en secondes.
mysql> select TIME_TO_SEC('22:23:00'); -> 80580 mysql> select TIME_TO_SEC('00:39:38'); -> 2378
DATABASE()
Retourne le nom de la base de données courante
mysql> select DATABASE(); -> 'test'
S'il n'y a pas de base de données courante, DATABASE()
retourne une chaîne vide.
SYSTEM_USER()
SESSION_USER()
Retourne le nom de l'utilisateur MySQL courant.
mysql> select USER(); -> 'davida@localhost'
Avec MySQL 3.22.11 ou plus récent, le nom de l'utilisateur courant contient le nom du de l'hôte client. On peut alors en extraire le nom du User.
mysql> select left(USER(),instr(USER(),"@")-1); -> 'davida'
PASSWORD(str)
Calcule un mot de passe à partir du texte de str
. C'est une fonction d'encryption utilisée par MySQL pour stocker les mots de passes dans la colonne Password
, de la table des droits des utilisateurs.
mysql> select PASSWORD('badpwd'); -> '7f84554057dd964b'
Le cryptage de PASSWORD()
n'est pas reversible. PASSWORD()
effectue un cryptage différent de celui d'Unix. Il ne faut pas croire que si le mot de passe de MySQL et d'Unix sont les mêmes, alors les deux valeurs cryptées seront les mêmes. Voir ENCRYPT()
.
ENCRYPT(str[,salt])
Crypte la chaîne str
en utilisant le cryptage d'Unix( crypt())
l. Le grain de sel est une chaîne avec deux caractères.
mysql> select ENCRYPT("hello"); -> 'VxuFAJXVARROc'
Si la commande crypt()
n'est pas disponible sur votre système, ENCRYPT()
retournera NULL
. ENCRYPT()
n'utilise que les 8 premiers caractères de la chaîne, sur certains systèmes. Cela dépendra du comportement de l'appel système : crypt()
.
str
en utilisant de mot de passe pass_str
. Pour décrypter le résultat, il faut utiliser DECODE()
. Le résultat est une chaîne binaire. Pour l'enregistrer, il faut l'affecter à une colonne de type BLOB
.
DECODE(crypt_str,pass_str)
Décrypte la chaîne cryptée crypt_str
, en utilisant le mot de passe pass_str
. crypt_str
doit être une chaîne retournée par ENCODE()
.
MD5(string)
Calcule la somme de vérification MD5 de ma chaîne. La valeur retournée est un nombre hexadécimal de 32 bits, utilisé comme clé.
mysql> select MD5("testing") -> 'ae2b1fca515949e5d54fb22b8ed95575'
Cette fonction est issue de "RSA Data Security, Inc. MD5 Message-Digest Algorithm".
LAST_INSERT_ID([expression ])
Retourne la dernière valeur générée automatiquement lors de la mise à jour d'une colonne de type AUTO_INCREMENT
Voir Section mysql_insert_id
.
mysql> select LAST_INSERT_ID(); -> 195
Le dernier ID généré est conservé par le serveur, sur la base d'un par connexion. Il ne sera pas changé par un autre client. Il ne sera même pas changé par la mise à jour d'une colonne de type AUTO_INCREMENT
. Si expression
est donné comme argument à LAST_INSERT_ID()
dans une clause , alors la valeur de l'argument est retournée, en tant que LAST_INSERT_ID()
. Cela peut être utile pour simuler des séquences. Par exemple :
mysql> create table sequence (id int not null); mysql> insert into sequence values (0);
Alors la table peut être utilisée pour générer une séquence de nombre comme ceci :
mysql> update sequence set id=LAST_INSERT_ID(id+1);
Il est possible de générer des séquences sans appeler LAST_INSERT_ID()
, mais l'interêt de cette fonction et que l'ID est conservé par le serveur en tant que dernière valeur générée. Il est ainsi possible d'obtenir un nouvel ID comme lors de la lecture de n'importe quelle colonne de type AUTO_INCREMENT
. Par exemple, LAST_INSERT_ID()
(sans argument) retournera un nouvel ID . La méthode C API mysql_insert_id()
peut aussi être utilisée pour obtenir une telle valeur.
X
au format'#,###,###.##'
avec D
décimales. Si D
vaut 0
, le résultat n'aura ni décimales, ni virgule.
mysql> select FORMAT(12332.1234, 2); -> '12,332.12' mysql> select FORMAT(12332.1,4); -> '12,332.1000' mysql> select FORMAT(12332.2,0); -> '12,332'
VERSION()
Retourne la version du serveur MySQL .
mysql> select VERSION(); -> '3.22.19b-log'
GET_LOCK(str,timeout)
Essaie d'obtenir le verrous nommé str
, avec un timeout de timeout
secondes. Retourne 1 si le verrous a pu être obtenu, 0 en cas d'échec, ou si une erreur est survenue (comme par exemple, plus de mémoire disponible, ou le thread a été tué par l'administrateur). Un verrou est libéré avec la fonction RELEASE_LOCK()
, avec l'exécution de la fonction GET_LOCK()
ou la mort du thread courant. Cette fonction peut être utilisée pour implémenter des verrous d'applications, ou simuler des verrous sur les enregistrements.
mysql> select GET_LOCK("lock1",10); -> 1 mysql> select GET_LOCK("lock2",10); -> 1 mysql> select RELEASE_LOCK("lock2"); -> 1 mysql> select RELEASE_LOCK("lock1"); -> NULL
Il faut noter que le deuxième appel à RELEASE_LOCK()
retourne NULL
car le verrou "lock1"
a été automatiquement libéré par le deuxième appel à GET_LOCK()
.
str
, obtenu par l'appel de GET_LOCK()
. Retourne 1 si le verrous a bien été libéré, et 0 si il n'était pas mis par ce thread (dans ce cas, il reste verrouillé), et si ce verrous n'existe pas. Le verrous n'existe pas tant qu'il n'a pas été créer par GET_LOCK()
ou si il a déjà été libéré.
BENCHMARK
exécute l'expression expression
count
fois. Cela permet de mesurer le temps que MySQL met à exécuter l'expression. Le résultat est toujours 0
. Le temps mis pour l'exécution de la commande est disponible sur l'affichage du client MySQL.
mysql> select BENCHMARK(1000000,encode("hello","goodbye")); +----------------------------------------------+ | BENCHMARK(1000000,encode("bonjour","ca va")) | +----------------------------------------------+ | 0 | +----------------------------------------------+ 1 row in set (4.74 sec)
Le temps affiché sur le client est le temps entre le début et la fin de l'exécution, et non pas le temps de travail du processeur. Il peut être nécessaire d'éxécuter plusieurs fois la commande, pour prendre en compte la charge de la machine.
GROUP BY
L'utilisation d'une fonction de regroupement dans une commande qui ne contient pas la clause GROUP BY
est équivalent à regrouper toutes les lignes.
COUNT(expression )
Retourne le nombre de lignes non-NULL
obtenue par une commande SELECT
.
mysql> select student.student_name,COUNT(*) from student,course where student.student_id=course.student_id GROUP BY student_name;
COUNT(*)
est optimisé pour compter très rapidement les lignes obtenues par un SELECT
sur une seule table, sans qu'aucune autre colonne ne soit demandée, et sans clause WHERE
. Par exemple :
mysql> select COUNT(*) from student;
COUNT(DISTINCT expression ,[expression ...])
Retourne le nombre de ligne distinctes.
mysql> select COUNT(DISTINCT results) from student;
Avec MySQL il est possible d'obtenir le nombre de combinaison d'expressions distinctes en donnant une liste d'expression. E, ANSI SQL, il aurait fallu concaténer les expressions avec CODE(DISTINCT ..)
.
AVG(expression )
Retourne la moyenne des valeurs de expression
.
mysql> select student_name, AVG(test_score) from student GROUP BY student_name;
MIN(expression )
MAX(expression )
Retourne le minimum ou le maximum de expression
. MIN()
et MAX()
peuvent travailler avec des chaînes. Dans ce cas, il retourne la chaîne minimum maximum .
mysql> select student_name, MIN(test_score), MAX(test_score) from student GROUP BY student_name;
SUM(expression )
Retourne la somme de expression
. Si l'ensemble n'a aucune ligne, le résultat est NULL
!
STD(expression )
STDDEV(expression )
Retourne la déviation standard de expression
. C'est une extension à la norme ANSI SQL. La fonction STDDEV()
est fourni pour assurer la comptabilité avec les bases Oracle.
BIT_OR(expression )
Retourne le OU logique bit-à-bit, effectué sur expression
. Ce calcul est fait sur 64 bits (précision de BIGINT
).
BIT_AND(expression )
Retourne le ET logique bit-à-bit, effectué sur expression
. Ce calcul est fait sur 64 bits (précision de BIGINT
).
MySQL permet une utilisation étendue de GROUP BY
. Il est possible de faire des calculs sur des colonnes dans le SELECT
même si elles n'apparaissent pas dans le GROUP BY
. Cela est possible pour n'importe quelle valeur de ce groupe. Cela permet de gagner en performance en évitant de faire des regroupements ou des tris sur des valeurs inutiles. Par exemple, il n'y a pas besoin de faire un regroupement avec customer.name
dans la requête suivante :
mysql> select order.custid,customer.name,max(payments) from order,customer where order.custid = customer.custid GROUP BY order.custid;
La norme ANSI SQL impose d'ajouter customer.name
dans la clause GROUP BY
. Avec MySQL, c'est redondant.
Il ne faut pas utiliser cette particularité si les noms de colonnes ne sont pas unique dans le groupe courant.
Dans certains cas, il est possible d'utiliser MIN()
et MAX()
pour obtenir la valeur d'une colonne spécifique, même si elle n'est pas unique. Par exemple, cette requête retourne la valeur de column
, de la ligne qui contient la colonne sort
la plus courte.
substr(MIN(concat(sort,space(6-longueur(sort)),column),7,longueur(column)))
Il faut noter que avec MySQL 3.22 (ou avant), ou en suivant la norme ANSI SQL, il ne faut pas utiliser d'expressions dans les clauses GROUP BY
ou ORDER BY
. Il faut alors contourner la difficulté en utilisant un alias.
mysql> SELECT id,FLOOR(value/100) AS val FROM Nom_table GROUP BY id,val ORDER BY val;
Avec MySQL 3.23, on peut écrire :
mysql> SELECT id,FLOOR(value/100) FROM Nom_table ORDER BY RAND();
CREATE DATABASE
CREATE DATABASE nom_base_de_donnees
CREATE DATABASE Nom_bdd
CREATE DATABASE
crée une base de donnée avec le nom Nom_bdd. Les règles qui régissent les nom de base de données sont détaillées dans la section 7.1.5 Noms de base de données, table, index, column et alias. MySQL retourne une erreur si la base de données existe déjà.
Avec MySQL, les bases sont représentées sous la forme de dossiers qui contiendront des fichiers, qui représenteront les tables. Etant donné qu'à la création d'une base, cette dernière est vide, CREATE DATABASE
se contente de créer un dossier dans le dossier données de MySQL.
Il est aussi possible de créer des bases avec la méthode mysqladmin.
12.1 Présentation des différents programmes MySQL.
DROP DATABASE
DROP DATABASE [IF EXISTS] Nom_bdd
DROP DATABASE
efface toutes les tables de la base , et efface aussi la base, i.e. le dossier. Il faut être TRES prudent avec cette commande.
DROP DATABASE
retourne le nombre de fichiers qui ont été effacés. Normalement, ce nombre correspond à trois fois le nombre de table, étant donné que chaque table a trois fichier, un fichier ``.ISD',' un fichier ``.ISM'' et un fichier ``.frm''.
MySQL 3.22 ou plus récent autorise l'utilisation du mot clé IF NOT EXISTS
, qui ne retourne pas d'erreur si la base à effacer n'existe pas.
Il est aussi possible d'effacer des bases avec la méthode mysqladmin. 12.1 Présentation des différents programmes MySQL.
CREATE TABLE
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] Nom_table (create_definition,...) [options_de_table] [commande_de_selection] create_definition: Nom_col type [NOT NULL | NULL] [DEFAULT valeur_par_defaut] [AUTO_INCREMENT] [PRIMARY KEY] [reference_definition] ou PRIMARY KEY (index_Nom_col,...) ou KEY [Nom_index] KEY(index_Nom_col,...) ou INDEX [Nom_index] (index_Nom_col,...) ou UNIQUE [INDEX] [Nom_index] (index_Nom_col,...) ou [CONSTRAINT symbole] FOREIGN KEY Nom_index(index_Nom_col,...) [reference_definition] ou CHECK (expression ) type: TINYINT[(longueur)] [UNSIGNED] [ZEROFILL] ou SMALLINT[(longueur)] [UNSIGNED] [ZEROFILL] ou MEDIUMINT[(longueur)] [UNSIGNED] [ZEROFILL] ou INT[(longueur)] [UNSIGNED] [ZEROFILL] ou INTEGER[(longueur)] [UNSIGNED] [ZEROFILL] ou BIGINT[(longueur)] [UNSIGNED] [ZEROFILL] ou REAL[(longueur,décimales)] [UNSIGNED] [ZEROFILL] ou DOUBLE[(longueur,décimales)] [UNSIGNED] [ZEROFILL] ou FLOAT[(longueur,décimales)] [UNSIGNED] [ZEROFILL] ou DECIMAL(longueur,décimales) [UNSIGNED] [ZEROFILL] ou NUMERIC(longueur,décimales) [UNSIGNED] [ZEROFILL] ou CHAR(longueur) [BINARY] ou VARCHAR(longueur) [BINARY] ou DATE ou TIME ou TIMESTAMP ou DATETIME ou TINYBLOB ou BLOB ou MEDIUMBLOB ou LONGBLOB ou TINYTEXT ou TEXT ou MEDIUMTEXT ou LONGTEXT ou ENUM(value1,value2,value3,...) ou SET(value1,value2,value3,...) index_Nom_col: Nom_col [(longueur)] reference_definition: REFERENCES Nom_table [(index_Nom_col,...)] [MATCH FULL | MATCH PARTIAL] [ON DELETE reference_option] [ON UPDATE reference_option] reference_option: RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT options_de_table: type = [ISAM | MYISAM | HEAP] ouauto_increment = # ouavg_row_longueur = # ouchecksum = [0 | 1] oucomment = "string" oulignes_max= # oulignes_min = # oupack_keys = [0 | 1] oupassword= "string" commande_de_selection: [ | IGNORE | REPLACE] SELECT ... (Un select valide)
CREATE TABLE
crée une table, de nom Nom_table, dans la base de donnés courante. Les règles qui régissent les nom de table sont détaillées dans 7.1.5 Noms de base de données, table, index, column et alias. MySQL retourne une erreur si il n'y a pas de base de données courante, ou la table existe déjà.
Avec MySQL 3.22 ou plus récent, on peut se référer à la table en utilisant la structure Nom_bdd.Nom_table
. Ceci fonctionne, qu'il y ait une base de données courante ou pas.
MySQL 3.23 autorise l'utilisation du mot clé TEMPORARY
lors de la création de table. Une table temporaire sera automatiquement effacée lorsque la connexion sera terminée. Cela permet à deux connexions différents d'utiliser le même nom de table temporaire, sans conflit l'un avec l'autre, ou avec une table existante (la table permanente est cachée jusqu'à ce que la table temporaire soit effacée).
MySQL 3.22 ou plus récent autorise l'utilisation du mot clé IF NOT EXISTS
, qui ne retourne pas d'erreur si la table à créer existe déjà.
Chaque table est representée par un ou plusieurs fichiers dans le dossier de la bas e de données. Dans le cas ou la table est de type ISAM, il y aura :
Pour plus d'information sur les propriétés des différents type de colonne, 7.2 Types de colonnes.
NULL
ni NOT NULL
n'a été précisé, alors la colonne est considéré comme de type NULL.
AUTO_INCREMENT
. A chaque insertion de la valeur ou de 0 dans une colonne de type AUTO_INCREMENT
, la valeur de la colonne est mise à value+1
, avec value
qui est la plus grande valeur dans la colonne de la table courante. AUTO_INCREMENT
commence à 1. Si la ligne contenant la plus grande valeur de la colonne est effacée, cette valeur sera réutilisée. Si toutes les lignes de la table sont effacée, AUTO_INCREMENT
recommence à 1. Il ne peux y avoir qu'une seule colonne de type AUTO_INCREMENT
par table, et cette colonne doit être indexée. Par souci de compatibilité avec ODBC, il est possible d'accéder à la dernière ligne insérée avec la requête suivante :
SELECT * FROM Nom_table WHERE auto_col IS NULL
Les valeurs NULL
sont gérées de manière différentes pour les colonnes de type TIMESTAMP. Il n'est pas possible de stocker la valeur NULL
dans une colonne de type TIMESTAMP, alors cette affectation conduit à affecter la date et l'heure courante à la place. A cause de ce comportement, les attributs NULL
et NOT NULL ne s'appliquent pas, et sont ignorées. D'un autre coté, afin de rendre
MySQL plus simple à utiliser, le serveur autorise l'affectation de NULL
aux colonnes de type TIMESTAMP
(ce qui est vrai), même si les colonnes de type TIMESTAMP
ne contiendront jamais réellement la valeur NULL. Cette information est accessible en utilisant la commande DESCRIBE Nom_table
qui détaille les colonnes de la table. Il est bon de rappeler que la valeur 0
est une valeur valide de TIMESTAMP
.
Si aucune valeur par défaut n'est précisé avec l'attribut DEFAULT,
MySQL en assignera automatiquement une. Si la colonne peut prendre la valeur NULL, alors
MySQL utilisera cette valeur par défaut. Sinon, son comportement dépendra du type de colonne :
AUTO_INCREMENT
, la valeur par défaut est 0
. Pour les colonnes ayant l'attribut AUTO_INCREMENT
, la valeur par défaut est la prochaine valeur de la séquence.
TIMESTAMP
, la valeur par défaut est le ``zéro'' . Pour la première colonne de type TIMESTAMP
, la valeur par défaut est la date et l'heure courante. 7.2.6 Types date et heure.
ENUM
, la valeur par défaut est la chaîne vide. Pour le type ENUM
, la valeur par défaut est la première valeur de l'énumération.
KEY
est un synonyme pour INDEX
.
UNIQUE
force la valeur à toujours prendre une valeur distincte. Une erreur surviendra lors de l'insertion d'une ligne qui doublera une ligne déjà existante.
PRIMARY KEY
est identique à l'attribut KEY
qui porterait le nom de PRIMARY
Une table ne peut avoir qu'une seule colonne avec l'attribut table PRIMARY KEY
. Si aucune colonne n'a de PRIMARY KEY
et qu'une application requiert la colonne de PRIMARY KEY
, MySQL retournera la première colonne ayant l'attribut UNIQUE.
PRIMARY KEY
peut être un index multi colonne. Mais il n'est pas possible de créer un index multi colonne qui aurait l'attribut PRIMARY KEY
. Pour cela, il faut utiliser la fonction PRIMARY KEY(index_Nom_col, ...)
, sous peine de ne voir que la première colonne porter l'attribut PRIMARY KEY
.
_2
, _3
, ...
), pour l rendre unique. La liste des noms d'index est accessible avec la requête : SHOW INDEX FROM Nom_table.
NULL
. Dans les autres cas, il faut absolument déclarer la colonne de type NOT NULL
pour ne pas générer une erreur.
Nom_col(longueur)
, il est possible de spécifier un index qui utilise seulement une partie de la colonne de type CHAR
or VARCHAR
. Cela rend l'index nettement plus petit et plus efficace. Indexes
.
BLOB
et TEXT
. mettre un index sur une telle colonne impose de préciser la longueur de la colonne dans l'index.
CREATE TABLE test (blob_col BLOB, index(blob_col(10)));
ORDER BY
ou GROUP BY
avec de colonnes de type TEXT
ou BLOB
, seuls les max_sort_longueur
premiers octets sont pris en compte. BLOB
.
FOREIGN KEY
, CHECK
et REFERENCES
ne font en réalité rien de spécial. Ils sont uniquement fournis pour assurer la compatibilité et la portabilité de programme SQL et de les faire tourner avec MySQL.
row longueur = 1 + (sum of column longueurs) + (number of NULL columns + 7)/8 + (number of variable-longueur columns)
options_de_table
et SELECT
ne sont disponibles qu'à partir de MySQL 3.23. Les différents types de tables sont :
Les options de table sont utilisées pour optimiser la gestion de la table. Dans la plus part des cas, ces options peuvent être ignorées. Ces options fonctionnent pour toutes les types de table, sauf indication contraire.
Lors de l'utilisation d'une tape de type MyISAM
table, MySQL utilise le produit max* avg_row_longueur
pour connaître la taille maximale de la table. Par défaut, la taille maximale de la table est 4Go (4 Giga octets) (ou 2Go, si le système ne les supporte pas.
CREATE STATEMENT
est spécifié après SELECT,
MySQL va créer de nouveaux champs pour chacun des éléments dans le SELECT
. Par exemple
mysql> CREATE TABLE test (a int not null auto_increment, primary key (a), key(b)) TYPE=HEAP SELECT b,c from test2;
Cette requête va créer une table de type HEAP
table avec 3 colonnes. Cette table sera automatiquement effacée si une erreur survient lors de la copie des données dans ma table.
Dans certains cas, MySQL spontanément les spécifications d'une colonne lors d'une commande de CREATE TABLE
(Cela peut aussi intervenir lors d'une commande with ALTER TABLE
.)
VARCHAR
d'une longueur de moins de 4 caractères sont changées en CHAR
.
VARCHAR
, TEXT
or BLOB
), toutes les colonnes de type CHAR
et de longueur supérieur à 3 caractères sont changées en colonne de type VARCHAR
.Cela ne change en rien l'utilisation de ces colonnes, cela modifie simplement la façon dont les colonnes sont stockées. MySQL effectue cette conversion car cela économise de la place, et rend les opérations sur la table plus rapides.
TIMESTAMP
doit être pair et compris dans l'intervalle de 2 à 14. En dehors de l'intervalle 2 à 14, la taille de l'affichage est ramenée à 14. En cas de nombre impair, le nombre est arrondi au nombre pair directement supérieur.
NULL
dans une colonne de type TIMESTAMP
, car une telle affectation revient à assigner la date et l'heure courante à la colonne. De ce fait, les attributs NULL
et NOT NULL
ne s'appliquent pas aux colonnes de type TIMESTAMP
, et sont ignorés. Lors d'une requête DESCRIBE Nom_table
MySQL répondra toujours que la colonne accepte les valeurs de type NULL
.
Pour savoir si MySQL a modifié spontanément le type d'une colonne, il faut utiliser la requête DESCRIBE Nom_table
après la création ou la modification de la table.
Certaines autres modifications de type peuvent intervenir lors de la compression de table avec la commande pack_isam
.
10.17 Quel sont les différents formats de lignes? Quand utiliser VARCHAR/CHAR
?.
ALTER TABLE
ALTER [IGNORE] TABLE Nom_table alter_spec [, alter_spec ...] alter_specification: ADD [COLUMN] create_definition [FIRST | AFTER column_name ] ou ADD INDEX [Nom_index] (index_Nom_col,...) ou ADD PRIMARY KEY (index_Nom_col,...) ou ADD UNIQUE [Nom_index] (index_Nom_col,...) ou ALTER [COLUMN] Nom_col {SET DEFAULT literal | DROP DEFAULT} ou CHANGE [COLUMN] old_Nom_col create_definition ou MODIFY [COLUMN] create_definition ou DROP [COLUMN] Nom_col ou DROP PRIMARY KEY ou DROP INDEX key_name ou RENAME [AS] new_Nom_table ou table_option
ALTER TABLE
modifie la structure d'une table existante. Par exemple, il est possible d'ajouter ou d'effacer des colonnes, de créer et détruire des index, de changer le type d'une colonne ou de la renommer, voire même de renommer la table elle-même. Il est aussi possible de changer le commentaire de la table et son type. Voir CREATE TABLE
.
Si, lors d'une modification de type de colonne, la commande DESCRIBE Nom_table
indique que la colonne n'a pas changé de type, il est possible que MySQL ait ignoré la modification pour une des raisons décrites dans 7.6.1 Modifications automatiques de type de colonne. Par exemple, si il existe plusieurs colonne de type de longueur variable, rien de sert de tenter de forcer une colonne du type VARCHAR
à CHAR
.
ALTER TABLE
fonctionne en effectuant une copie temporaire de la table originale. La modification est effectuée sur la copie, puis l'originale est remplacée par la copie modifiée. Toutes les mises à jours sont automatiquement appelé, et sont faites dans un mode sans erreur. Pendant la modification, la table originale est toujours accessible en lecture par les autres clients. Les mises à jour et les écritures sont reportées jusqu'à la fin de la modification.
ALTER TABLE
, il faut avoir les droits pour select, insert, delete, update, create et drop sur la table.
IGNORE
est une extension MySQL de la norme ANSI SQL92. Il permet de contrôler la façon avec laquelle réagit si il trouve des doublons dans une colonne de clés uniques. Si n'est pas précisé, la copie est annulée à la première erreur, et la modification est annulée. Si est précisé, alors la première occurrence d'une clés en double sera utilisée, les autres occurrences étant ignorées et effacées.
ADD
, ALTER
, DROP
et CHANGE
dans une commande ALTER TABLE
. C'est une extension de MySQL à la norme ANSI SQL92 : cette dernière ne permet qu'une seule de ces clauses à chaque commande.
CHANGE Nom_col
, DROP Nom_col
et DROP INDEX
sont des extensions de MySQL à la norme ANSI SQL92
CHANGE Nom_col
, DROP Nom_col
et DROP INDEX
sont des extensions de MySQL à la norme ANSI SQL92 .
MODIFY
est une extension Oracle à ALTER TABLE
.
COLUMN
est simplement de la décoration et peut être ignoré.
ALTER TABLE Nom_table RENAME AS new_name
'' sans aucune autre option, permet de renommer la table. MySQL va simplement renommer les fichiers correspondant à la table Nom_table
. Il n'y a pas de création de table temporaire.
create_definition
utilise la même syntaxe que les clauses ADD
et CHANGE
, ainsi que CREATE TABLE.
Cette inclus le nom de la colonne, et pas seulement le type de colonne. Voir CREATE TABLE
.
CHANGE old_Nom_col create_definition
permet de changer le nom d'une colonne. Pour cela, il faut spécifier l'ancien et le nouveau nom de la colonne, ainsi que le type courant de la colonne. Par exemple, pour renommer une colonne de type INTEGER
de 'a' en 'b', la commande suivante est valable :
mysql> ALTER TABLE t1 CHANGE a b INTEGER;
Pour changer le type de la colonne mais pas son nom, la syntaxe de CHANGE
requiert deux noms de colonnes, même si ils sont identiques. Par exemple :
mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
Cependant, à partir de MySQL 3.22.16a, il est possible d'utiliser la clause MODIFY
pour changer le type de la colonne sans le renommer:
mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
CHANGE
ou MODIFY
pour réduire la taille d'une colonne qui possède un index (par exemple, un index sur les 10 premiers caractères d'une colonne de type VARCHAR
), il est impossible de rendre la colonne plus petite que ne le requiert l'index.
CHANGE
ou MODIFY
, MySQL essaie de convertir au mieux les informations d'un type à l'autre.
FIRST
ou ADD ... AFTER Nom_col
pour ajouter une colonne à une position donnée, dans une table. Par défaut, l'ajout de fait après la dernière colonne.
ALTER COLUMN
spécifie une nouvelle valeur par défaut, ou bien efface l'ancienne valeur. Si la valeur par défaut de la colonne est effacée, et que la colonne peut être NULL
, alors la nouvelle valeur par défaut est NULL
.Si la colonne ne peut pas être NULL
, alors MySQL assigne une valeur par défaut arbitraire, comme décrit dans le paragraphe CREATE TABLE
.
DROP INDEX
efface un index. C'est une extension de MySQL à la norme ANSI SQL92 .
DROP PRIMARY KEY
efface la colonne qui porte l'attribut PRIMARY KEY
. Si une telle colonne n'existe pas, la première colonne de type UNIQUE
est effacée à la place. (MySQL utilise la première colonne UNIQUE
comme PRIMARY KEY
si aucune PRIMARY KEY
n'est spécifiée.)
mysql_info()
, il est possible de savoir combien de ligne ont été copiée, et (quand l'option IGNORE
était mise), le nombre de lignes qui furent effacées, à cause de la duplication de clés.
FOREIGN KEY
, CHECK
et REFERENCES
ne font en réalité rien de spécial. Ils sont uniquement fournis pour assurer la compatibilité et la portabilité de programme SQL et de les faire tourner avec MySQL.
Voici quelques exemples d'utilisation de la commande ALTER TABLE
. On supposera que la table t1
, créée ci-dessous, existe :
mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));
Renomme la table de t1
et t2
:
mysql> ALTER TABLE t1 RENAME t2;
Change le type de la colonne a
de INTEGER
en TINYINT NOT NULL
(mais ne change pas le nom), et change le type de la colonne b
de CHAR(10)
en CHAR(20)
et renomme cette colonne en c
.
mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
Ajoute une nouvelle colonne d
, de type TIMESTAMP
.
mysql> ALTER TABLE t2 ADD d TIMESTAMP;
Ajoute un index sur la colonne d
, et fait de la colonne a une PRIMARY KEY
mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);
Efface la colonne c
:
mysql> ALTER TABLE t2 DROP COLUMN c;
Ajoute une nouvelle colonne de type AUTO_INCREMENT
integer
, nommée c
:
mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD INDEX (c);
Il faut remarquer que la colonne c
a été indexée, car les colonnes de type AUTO_INCREMENT
doivent être indexée, ce qui implique c
doit avoir l'attribut NOT NULL
, puisque les colonnes indexées ne peuvent pas avoir de valeur à NULL
.
OPTIMIZE TABLE
OPTIMIZE TABLE Nom_table
OPTIMZE TABLE
est à utiliser après avoir effacer de grandes parties d'une table, pour après des modifications majeures sur une table à longueur de ligne variable. Les index des lignes effacées sont conservés, et l'opération INSERT
les réutilise, et écrase mes anciennes lignes. La commande OPTIMIZE TABLE
permet de récupérer l'espace inutilisé des tables.
OPTIMIZE TABLE
fonctionne en effectuant une copie temporaire de la table originale. La modification est effectuée sur la copie, puis l'originale est remplacée par la copie modifiée. Toutes les mises à jours sont automatiquement appelé, et sont faites dans un mode sans erreur. Pendant la modification, la table originale est toujours accessible en lecture par les autres clients. Les mises à jour et les écritures sont reportées jusqu'à la fin de la modification.
DROP TABLE
DROP TABLE [IF EXISTS] Nom_table [, Nom_table,...]
DROP TABLE
efface une ou plusieurs tables. Toutes les données et le fichier de définition sont effacés. Cette commande est irréversible
MySQL 3.22 ou plus récent autorise l'utilisation du mot clé IF EXISTS
, qui ne retourne pas d'erreur si la table à effacer n'existe pas.
DELETE
DELETE [LOW_PRIORITY] FROM Nom_table [WHERE where_definition] [LIMIT rows]
DELETE
efface les lignes de la table Nom_table
qui satisfont les conditions données par where_definition
, et retourne le nombre de ligne effacées.
Une commande DELETE
sans clause WHERE
s'applique à toutes les lignes, c'est à dire que la table est vidée de toutes ses données (mais elle n'est pas effacée). MySQL recrée alors la table, mais vide, ce qui est nettement plus rapide que d'effacer les lignes unes à unes. Dans ce cas particulier, MySQL retourne 0 (. (MySQL ne peut pas connaître le nombre de ligne de la table sans l'avoir ouverte, car la recréation est faite sans accéder à la table), return the number of rows that were actually deleted, since the recreate is done without opening the data files). Tant que le fichier ``Nom_table.frm' est valide, il est possible de recréer la table, même si le fichier de données est corrompu).'
Pour obtenir le nombre de ligne effacées lors de l'effacement de la table, il est toujours possible de sacrifier la vitesse d'exécution, et d'utiliser la commande suivante :
mysql> DELETE FROM Nom_table WHERE 1>0;
Cette requête est particulièrement LENTE, car l'effacement se fait ligne à ligne, à cause de la clause WHERE
L'option LOW_PRIORITY
permet de reporter l'effacement jusqu'au moment ou il ne reste plus personne qui lise la table.
Les ligne effacées sont conservées dans une liste, et les insertions ultérieurs réutiliseront cette place. Pour forcer la récupération de cette place, il faut utiliser la commande OPTIMIZE TABLE
ou bien l'utilitaire isamchk
pour réorganiser les tables. OPTIMIZE TABLE
est plus simple, mais isamchk
plus rapide. OPTIMIZE TABLE
.
L'option LIMIT
, spécifique à MySQL, permet d'indiquer au serveur le nombre maximum de ligne à effacer. Cela permet d'éviter qu'une commande DELETE
ne prenne trop de temps. Il suffit alors de répéter la commande jusqu'à ce qu'elle ait effacé moins de ligne que LIMIT
.
SELECT
SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [DISTINCT | DISTINCTROW | ALL] select_expression,... [INTO OUTFILE 'Nom_fichier' export_options] [FROM table_references [WHERE where_definition] [GROUP BY Nom_col,...] [HAVING where_definition] [ORDER BY {unsigned_integer | Nom_col | formula} [ASC | DESC] ,...] [LIMIT [offset,] rows] [PROCEDURE procedure_name] ]
SELECT
est utilisé pour obtenir des lignes à partir d'une ou plusieurs tables. select_expression
indique les colonnes à lire. SELECT
peut aussi être utilisé pour exécuter des calculs sans rapport avec aucune table. Par exemple :
mysql> SELECT 1 + 1; -> 2
Toutes les options doivent impérativement être dans l'ordre indiqué ci dessus. Par exemple, une clause HAVING
doit être après GROUP BY
et avant la clause ORDER BY
.
SELECT
peut utiliser des alias, introduit par le mot clé AS
. L'alias est utilisé comme un nom de colonne, et peut être repris dans une clause ORDER BY
ou HAVING
. Par exemple:
mysql> select concat(last_name,', ',first_name) AS full_name from maTable ORDER BY full_name;
FROM table_references
indique les noms des tables qu'il faut interroger. Si il y a plusieurs tables, il vaut mieux utiliser la clause join
. JOIN
.
Nom_col
, Nom_table.Nom_col
or Nom_bdd.Nom_table.Nom_col.
Il n'y a pas besoin de préciser les préfixes Nom_table
ou Nom_bdd.Nom_table
lors d'un SELECT
à moins que les noms soient ambiguÎs. 7.1.5 Noms de base de données, table, index, column et alias, pour des exemples sur les ambiguïtés qui peuvent apparaître.
Nom_table [AS] Nom_alias
.
mysql> select t1.name, t2.salary from employee AS t1, info AS t2 where t1.name = t2.name; mysql> select t1.name, t2.salary from employee t1, info t2 where t1.name = t2.name;
ORDER BY
et GROUP BY
en utilisant leur nom, leurs alias ou leur positions. Les colonnes sont positionnées à partir de 1.
mysql> select college, region, seed from tournament ORDER BY region, seed; mysql> select college, region AS r, seed AS s from tournament ORDER BY r, s; mysql> select college, region, seed from tournament ORDER BY 2, 3;
Pour trier dans l'ordre descendant, il faut ajouter le mot clé DESC
après le nom de la colonne, dans la clause ORDER BY
. Par défaut, l'ordre ascendant est utilisé, et peut être explicitement demandé en utilisant le mot clé ASC
HAVING
peut faire référence à n'importe quelle colonne ou alias présent dans select_expression
. Cette clause est évaluée en dernier, juste avant que les lignes soient envoyées au client, sans aucune optimisation. Il ne faut pas utiliser HAVING
là WHERE
où est plus efficace. Par exemple, il ne faut pas écrire :
mysql> select Nom_col from Nom_table HAVING Nom_col > 0;
A la place, il vaut mieux écrire :
mysql> select Nom_col from Nom_table WHERE Nom_col > 0;
A partir de MySQL 3.22.5, on peut écrire des requêtes telles que:
mysql> select user,max(salary) from users group by user HAVING max(salary)>10;
Dans les versions anciennes de MySQL , il était possible d'écrire :
mysql> select user,max(salary) AS sum from users group by user HAVING sum>10;
STRAIGHT_JOIN
force l'optimiseur à regrouper les tables dans l'ordre dans lequel elles sont spécifiées dans la FROM
. Cela permet d'accélérer le traitement d'une requête. EXPLAIN
.
SQL_SMALL_RESULT
peut être utilisé avec les clauses GROUP BY
ou DISTINCT
pour indiquer à l'optimiseur que le résultat sera de petite taille. Dans ce cas, MySQL va utiliser des tables temporaires d'accès rapide, pour enregistrer les tables de résultat, plutot que de faire des tries. SQL_SMALL_RESULT
est une extension MySQL de ANSI SQL92.
LIMIT
peut être utilisée pour restreindre le nombre de lign retournée SELECT
. LIMIT
a un ou deux arguments numériques.. Le premier indique l'index de la ligne de début, et le deuxième indique le nombre de ligne à retourner. L'indexe de la ligne initiale est 0.
mysql> select * from table LIMIT 5,10; # retourne les lignes 6-15
Si un seul argument est fourni à LIMIT, il indique le nombre de ligne à retourner.
mysql> select * from table LIMIT 5; # retourne les 5 premiere lignes
LIMIT n
et LIMIT 0,n
sont équivalents.
SELECT ... INTO OUTFILE 'Nom_fichier'
de la syntaxe de SELECT
écrit les lignes selectionnées dans un fichier. Les fichiers créés sont écrit sur le serveur, et ne doit pas exister au moment de l'écriture (cela évite d'écraser le fichier /etc/passwd, par exemple). Il faut avoir les droits d'écriture. SELECT ... INTO OUTFILE
est le contraire de la commande LOAD DATA INFILE
; qui importe les lignes à partir d'un fichier. L'expression export_options
est constituée des même champs FIELDS
et LINES
que dans la commande LOAD DATA INFILE
. section LOAD DATA
. Dans le fichier texte résultant de la commande SELECT ... INTO OUTFILE
, seuls, les caractères suivants sont précédé du caractère d'échappement, précisé avec ESCAPED BY
:
ESCAPED BY
FIELDS TERMINATED BY
LINES TERMINATED BY
De plus, le caractère ASCII 0
est converti en ESCAPED BY
suivi de 0 (ASCII 48
). La raison de l'ajout du caractère d'échappement après les caractères FIELDS TERMINATED BY
, ESCAPED BY
ou LINES TERMINATED BY
,est que cela permet la relecture du fichier. Le caractère ASCII 0
est échappé pour le rendre plus lisible par les éditeurs. Et comme le fichier résultant n'a pas à se conformer à la norme SQL, ce sont les seuls caractères à être échappés.
JOIN
MySQL utilise les syntaxes suivantes pour les commandes de JOIN
:
table_reference, table_reference table_reference [CROSS] JOIN table_reference table_reference INNER JOIN table_reference table_reference STRAIGHT_JOIN table_reference table_reference LEFT [OUTER] JOIN table_reference ON conditional_expression table_reference LEFT [OUTER] JOIN table_reference USING (column_list) table_reference NATURAL LEFT [OUTER] JOIN table_reference { oj table_reference LEFT OUTER JOIN table_reference ON conditional_expression }
La dernière syntaxe LEFT OUTER JOIN
n'existe que pour assurer la compatibilité avec ODBC.
mysql> select t1.name, t2.salary from employee AS t1, info AS t2 where t1.name = t2.name;
INNER JOIN
et ,
(comma) sont équivalents. Les deux effectuent un regroupement des tables utilisées. Normalement, il faut préciser comment les tables sont reliées avec la condition WHERE
.
ON
est identique à WHERE.
LEFT JOIN
, une ligne dont toutes les colonnes sont mises à NULL
est générée. Ceci permet de rechercher les lignes d'une table qui n'ont pas de contrepartie dans une autre table.
mysql> select table1.* from table1 LEFT JOIN table2 ON table1.id=table2.id where table2.id is NULL;
Cet exemple recherche toutes les lignes dans la table1
avec une colonne id
qui n'est pas présent dans la table table2
(i.e., toutes les lignes de la table table1
qui n'ont pas de ligne correspondantes dans la table table2
). Cela implique que a été déclaré table1.id
, bien entendu !
USING
column_list
spécifie une liste de nom de colonne qui doivent exister dans toutes les tables. Une utilisation telle que
A LEFT JOIN B USING (C1,C2,C3,...)
Correspond à l'utilisation d'une clause ON
comme ceci :
A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,...
NATURAL LEFT JOIN
de deux tables est équivalent à utilisation de la clause LEFT JOIN
avec USING
, en précisant les noms de toutes les colonnes qui existent dans les deux tables.
STRAIGHT_JOIN
est identique à JOIN
, à l'exception du fait que la table de gauche est lue avant la table de droite. Cela est pratique pour les (rares) cas où l'optimiseur de regroupement utilise les tables dans le mauvais ordre .
Quelques exemples
mysql> select * from table1,table2 where table1.id=table2.id; mysql> select * from table1 LEFT JOIN table2 ON table1.id=table2.id; mysql> select * from table1 LEFT JOIN table2 USING (id); mysql> select * from table1 LEFT JOIN table2 ON table1.id=table2.id LEFT JOIN table3 ON table2.id=table3.id;
INSERT
INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] Nom_table [(Nom_col,...)] VALUES (expression,...),(...),... ou INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] Nom_table [(Nom_col,...)] SELECT ... ou INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] Nom_table SET Nom_col=expression, Nom_col=expression, ...
INSERT
insère une nouvelle ligne dans une table existante.. La forme de INSERT ... VALUES
est basée sur des colonnes explicitement précisée. forme de INSERT ... SELECT
insère des données depuis une autre table. La forme de INSERT ... VALUES
avec plusieurs valeurs est acceptée MySQL à partir de la version 3.22.5 . La syntaxe Nom_col=expression
est accepté par MySQL à partir de la version 3.22.10.
Nom_table
est le nom de la table dans laquelle les lignes vont être insérée. La liste de nom de colonne ou la clause SET
indique quelles colonnes vont être assignées.
INSERT ... VALUES
or INSERT ... SELECT
, alors des valeurs doivent être fournies pour toutes les colonnes dans la liste de VALUES()
. Pour connaître l'ordre des colonnes, il faut utiliser la commande DESCRIBE Nom_table
.
CREATE TABLE
.
expression
peut faire référence à n'importe quelle colonne déjà nommée dans la liste des colonnes. Par exemple :
mysql> INSERT INTO Nom_table (col1,col2) VALUES(15,col1*2);
Mais pas ceci :
mysql> INSERT INTO Nom_table (col1,col2) VALUES(col2*2,15);
LOW_PRIORITY
permet de différer une exécution jusqu'à ce qu'il n'y ait plus de client qui lisent la table.
PRIMARY
or UNIQUE
, de ne pas renvoyer d'erreur si une insertion essaie de doubler une clé déjà existante. Si cette option n'est pas précisée, l'insertion est annulée à partir de la ligne erronée. Le nombre de ligne correctement insérées est accessible avec mysql_info()
.
DONT_USE_DEFAULT_FIELDS
, une commande INSERT
devra avoir la liste complète des colonnes qui requière une valeur non-NULL.
INSERT INTO ... SELECT
ORDER BY
FROM
du SELECT
, car la norme ANSI SQL l'interdit (en effet, le SELECT
pourrait trouver des lignes qui viennent juste d'être insérée. Utiliser des sous-selections serait encore pire).
Les colonnes de type AUTO_INCREMENT
fonctionnent de la même façon.
Lors de l'utilisation de INSERT ... SELECT
ou INSERT ... VALUES
avec des listes de plusieurs lignes, la fonction mysql_info()
permet d'obtenir des informations sur la requête. Le format de la réponse est comme suite :
Records: 100 Duplicates: 0 Warnings: 0
Duplicates
indique le nombre de lignes qui n'a pas pus être insérées car elles tentaient de doubler une clé primaire.. Warnings
indique le nombre d'insertions qui ont générer une erreur lors de l'insertion. Warnings
surviennent lorsqu'il y a une tentative:
NULL
dans une colonne déclarée NOT NULL
.
'10.34 a'
. Dans ce cas, les résidus inutiles sont éliminés. Si la valeur ne peut pas être interprétée, la valeur 0
est assignée à la place.
CHAR
, VARCHAR
, TEXT
ou BLOB
qui excède la longueur maximale. La valeur est alors tronquée à la taille maximale de la colonne.
L'option DELAYED
pour la commande INSERT
est une caractéristique MySQL qui est très utile lorsque les clients ne peuvent pas attendre la fin de l'insertion. C'est utilisé habituellement par MySQL pour remplir des historiques, et que périodiquement, une longue commande SELECT
est effectuée. DELAYED
a été introduit à partir de MySQL 3.22.15. C'est une extension MySQL à la norme ANSI SQL92.
Un autre avantage majeur de l'utilisation de la commande INSERT DELAYED
est que les insertions sont regroupées et traitées en même temps. C'est une manière plus rapide que d'effectuer autant d'insertions unitaires.
Il faut noter que les insertions en attente sont gardées en mémoire vive, jusqu'à ce qu'elles soient insérées dans la table. Cela signifie que si le processus mysqld
est brutalement interrompu (kill -9
) ou si mysqld
se termine inopinément, les lignes ne seront pas écrites sur le disque, et ainsi perdues !
Les événements suivants surviennent lors de l'utilisation de l'option DELAYED
des commandes INSERT
ou REPLACE
. Dans la description qui suit, le ``thread'' est le thread qui a recu la commande INSERT DELAYED
et ``handler'' est le thread qui va gérer les INSERT DELAYED
pour une table particulière.
DELAYED
pour une table, le thread handler est crée pour gérer toutes les commandes DELAYED
pour la table, si un tel thread n'existe pas.
DELAYED
, et si non, il lui dit de le faire. Le verrou DELAYED
peut être obtenu même si d'autres threads ont déjà obtenu un verrou de READ
ou WRITE
sur la table. Cependant, le handler va attendre que tous les verrous ALTER TABLE
ou FLUSH TABLES
soient libérés, afin de s'assurer que la table est bien à jour.
AUTO_INCREMENT
qu'il pourrait attendre, car ces informations ne sont connues qu'après l'insertion proprement dite. De la même façon, mysql_info()
risque de retourner des informations incohérentes.
delayed_insert_limit
lignes écrites, le handler vérifie si il n'y a pas de commande SELECT
en attente. Si c'est le cas, il s'arrête, et l'exécute avant de continuer.
INSERT DELAYED
n'est reçue dans un délai de delayed_insert_timeout
secondes, le handler se termine.
delayed_queue_size
lignes en attente d'insertion, le thread attend jusqu'à ce qu'il y ait de la place dans la queue. Ce permet de contrôler la quantité de mémoire utilisé pour les queues d'attentes.
delayed_insert
dans la colonne de Command
. Il sera automatiquement effacé lors d'une commande FLUSH TABLES
ou KILL thread_id
. Cependant, il enregistrera les lignes dans la table avant de quitter. Durant cette période, le handler n'acceptera plus aucune nouvelle commande INSERT
d'un autre thread. Si une nouvelle commande an INSERT DELAYED
est éxécutée, un nouveau handler sera créé.
INSERT DELAYED
ont une priorité supérieure aux commandes INSERT
, si un handler est déjà en fonctionnement. Toutes les autres commandes doivent attendre que la queue d'attente du handler soit vide (même par un kill).
INSERT DELAYED :
Ces variables sont accessibles avec la commande SHOW STATUS
ou, en ligne, avec mysqladmin extended-status
.
REPLACE
REPLACE [LOW_PRIORITY | DELAYED] [INTO] Nom_table [(Nom_col,...)] VALUES (expression,...) ou REPLACE [LOW_PRIORITY | DELAYED] [INTO] Nom_table [(Nom_col,...)] SELECT ... ou REPLACE [LOW_PRIORITY | DELAYED] [INTO] Nom_table SET Nom_col=expression, Nom_col=expression,...
REPLACE
fonctionne exactement comme INSERT
, mais si une ligne d'une table a une colonne qui porte l'attribut unique , REPLACE
pourra remplacer cette ligne par une nouvelle ligne, tout en gardant la même valeur dans la colonne de type unique. Pour plus de détails, voir INSERT
.
LOAD DATA INFILE
LOAD DATA [LOCAL] INFILE 'file_name.txt' [REPLACE | IGNORE] INTO TABLE nom_table [FIELDS [TERMINATED BY '\t'] [OPTIONALLY] ENCLOSED BY ''] [ESCAPED BY '\\' ]] [LINES TERMINATED BY '\n'] [IGNORE number LINES] [(nom_colonne,...)]
La commande LOAD DATA INFILE
lit des lignes à partir d'un fichier, et le transforme en table, à très grande vitesse. Si l'option LOCAL
est précisée, le fichier est lu depuis le client (cette fonction est disponible à partir la version 3.22.6 de MySQL.)
Pour des raisons de sécurité, lors de la lecture de fichier situé sur le serveur, les fichiers doivent être disponibles dans le dossier de MySQL, ou bien lisible par tous. De plus, pour utiliser LOAD DATA INFILE
sur des fichiers serveurs, il faut avoir les droits fichiers.
Utiliser l'option LOCAL
est un peu plus lente que l'option par défaut, car le contenu des fichiers doit du client vers le serveur. D'un autre coté, il n'y plus de problème de droits d'accès.
L'utilitaire mysqlimport
assure aussi l'importation de fichier. Il le fait en envoyant une requête LOAD DATA INFILE
au serveur. L'option –local
force mysqlimport
à lire le fichier depuis l'hôte client. Si le client et le serveur supporte le protocole compressé, l'option --compress
donnera de meilleures performances sur des réseaux chargés.
Pour retrouver les fichiers sur le serveur, le serveur utilise les règles suivantes :
Il faut noter que ces règles signifie que le fichier ``./monFichier.txt'' sera lu depuis le dossier données du serveur, tandis que ``myfile.txt'' sera lu depuis le dossier de la base de données courante. Il faut aussi noter qu'avec la commande ci-dessous, le fichier est lu depuis le dossier de la base db1
, et non pas db2
:
mysql> USE db1; mysql> LOAD DATA INFILE "./data.txt" INTO TABLE db2.my_table;
Les options REPLACE
et IGNORE
règlent la gestion index redondants, dans les colonnes de type unique. Avec REPLACE
, la nouvelle ligne remplacera l'ancienne, avec la même valeur d'index. Avec IGNORE
, la nouvelle ligne sera ignorée. Si rien n'est précisé, une erreur surviendra lors de la tentative d'insertion du doublon, et le reste du fichier sera ignoré.
Lors du chargement de lignes à partir d'un fichier local et avec l'option LOCAL
, le serveur n'a aucun moyen d'interrompre la transmission du fichier durant l'opération, alors le comportement par défaut est IGNORE
.
DATA INFILE
est la commande complémentaire de SELECT ... INTO OUTFILE
. SELECT
. Pour écrire des lignes depuis une base de données vers un fichier, il faut utiliser SELECT ... INTO OUTFILE
. Pour lire des lignes depuis un fichier vers une base, il faut utiliser LOAD DATA INFILE
. La syntaxe des clauses FIELDS
et LINES
est la même pour les deux commandes. Ces deux clauses sont optionnelles, mais FIELDS
doit impérativement précéder LINES
si les deux sont présents.
Si la clause est FIELDS
présente, alors chacune des sous clauses (TERMINATED BY
, [OPTIONALLY] ENCLOSED BY
t ESCAPED BY
) sont optionnelles, mais il faut au moins en spécifier une.
Si la clause FIELDS
n'est pas spécifiée, les valeurs par défaut sont les suivantes :
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
Si la clause LINES
n'est pas spécifiée, les valeurs par défaut sont les suivantes :
LINES TERMINATED BY '\n'
En bref, les options par défaut de LOAD DATA INFILE
fonctionnent comme suit :
Dans le sens inverse, les options par défaut de SELECT ... INTO OUTFILE
fonctionnent comme suit :
Il faut noter que pour écrire write FIELDS ESCAPED BY '\\'
, il faut écrire 2 backslash pour en avoir un de lu.
L'option IGNORE number LINES
permet d'ignorer les premières lignes, qui contiendrait un entête, par exemple.
mysql> LOAD DATA INFILE "/tmp/Nom_fichier" into table test IGNORE 1 LINES;
Pour pouvoir écrire un fichier avec SELECT ... INTO OUTFILE
, puis le relire LOAD DATA INFILE
ultérieurement avec, il est impératif que les options de lecture et d'écriture soient les mêmes. Sinon, l'interprétation du fichier à la relecture sera erronée. Par exemple, un fichier est écrit avec SELECT ... INTO OUTFILE
avec des virgules comme délimiteur de champs :
mysql> SELECT * FROM table1 INTO OUTFILE 'data.txt' FIELDS TERMINATED BY ',' FROM ...
Pour relire ce fichier, la bonne commande est :
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY ',';
Si, au contraire, le fichier est relu avec la commande ci-dessous, la relecture sera erronée, car les délimiteurs attendus sont des tabulations :
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY '\t';
Il est probable que le fichier soit interprété comme un seul champs.
LOAD DATA INFILE
peut aussi lire des fichiers issues d'autres sources. Par exemple, un fichier au format dBase a des champs séparés par des virgules, et insérés dans des doubles guillemets. Si les lignes dans le fichier sont terminées par des nouvelles lignes, la commande suivante permettra d'acquérir un fichier au format.
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE Nom_table FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';
Les options FIELDS
ou LINES
peuvent être des chaînes vides. Si ils ne sont pas vides, les options FIELDS [OPTIONALLY] ENCLOSED BY
et FIELDS ESCAPED BY
doivent être une chaîne d'un seul caractère. Les options FIELDS TERMINATED BY
et LINES TERMINATED BY
peuvent avoir un ou plusieurs caractères. Par exemple, si les lignes sont terminées par la paire retour-chariot/nouvelle-ligne, il est possible d'utiliser l'option LINES TERMINATED BY '\r\n'.
Contrôle les caractères qui entoure les champs. Lors de l'exportation(SELECT ... INTO OUTFILE
), l'absence de l'option OPTIONALLY
force tous les champs à être entouré par le caractère ENCLOSED BY
. Par exemple, en utilisant la virgule comme délimiteur de champs :
"1","une chaîne","100.20" "2"," une chaîne contenant une , virgule","102.20" "3"," une chaîne contenant un \" guillemet","102.20" "4"," une chaîne contenant un \", guillemet et une virgule","102.20"
L'option OPTIONALLY
force l'utilisation du caractère ENCLOSED BY
seulement pour les champs de type CHAR
et VARCHAR.
1," une chaîne ",100.20 2," une chaîne contenant une , virgule ",102.20 3," une chaîne contenant un \" guillemet ",102.20 4," une chaîne contenant un \", guillemet et une virgule ",102.20
On peut noter que les occurrences du caractère ENCLOSED BY
situés dans une chaîne sont toujours échappée, grÅce au caractère ENCLOSED BY
. On peut aussi noter que si le caractère d'échappement est une chaîne vide, le fichier ne pourra pas être relu correctement par LOAD DATA INFILE.
Par exemple, le fichier de sortie ci-dessus, va devenir le fichier de sortie ci-dessous, si le caractère d'échappement est vide. Lors de la relecture, un problème surviendra surement durant la deuxième ligne :
1," une chaîne ",100.20 2," une chaîne contenant une , virgule ",102.20 3," une chaîne contenant un " guillemet ",102.20 4," une chaîne contenant un \", guillemet et une virgule ",102.20
En entrée, le caractère est éliminé à la fin de chaque champs. (ceci est vrai, qu'il y ai l'option OPTIONALLY
ou pas. OPTIONALLY
n'a pas d'impact sur la procédure d'acquisition). Les occurrences du caractère ENCLOSED BY
précédés du caractère d'échappement ESCAPED BY
sont considérés comme une partie du champs. De plus, les caractères ENCLOSED BY
doublés sont considérés comme une seule occurrence. Par exemple, le caractère ENCLOSED BY
est '"'
alors, les lignes suivantes deviennent :
"Le ""GRAND"" chef" -> Le "GRAND" chef Le "GRAND" chef -> Le "GRAND" chef Le ""GRAND"" chef -> Le ""GRAND"" chef
FIELDS ESCAPED BY
contrôle l'écriture et la lecture des caractères spéciaux . Si l'option FIELDS ESCAPED BY
n'est pas une chaîne vide, il sert de préfixe dans les cas suivants
FIELDS ESCAPED BY
FIELDS [OPTIONALLY] ENCLOSED BY
FIELDS TERMINATED BY
et LINES TERMINATED BY
0
(qui sera en fait écrit avec la séquence caractère d'échappement suivi de 0 )
Si le caractère FIELDS ESCAPED BY
est une chaîne vide, aucun caractère ne sera échappé. Ce n'est pas une très bonne idée, surtout si certains champs contiennent l'un des caractères de la liste ci-dessus.
En lecture, si le caractère FIELDS ESCAPED BY
n'est pas une chaîne vide, les occurrences de ce caractère seront éliminées, et le caractère suivant sera lu littéralement, comme une partie du champs. Exceptions faites de ``0'' et ``N'' (i.eI., \0
ou \N
avec ``\' 'comme caractère d'échappement). Ces séquences seront interprétées comme ASCII 0
(le caractère nul) et NULL
. Voir ci dessous pour les règles de sauvegarde NULL
.
Pour plus d'informations à propos des séquences d'échappement, Literals
.
Dans certains cas, les options FIELDS
et LINES
de interagissent :
LINES TERMINATED BY
est une chaîne vide, et FIELDS TERMINATED BY
est une chaîne non vide, les lignes seront aussi terminées FIELDS TERMINATED BY
.
FIELDS TERMINATED BY
et FIELDS ENCLOSED BY
sont tous les deux des chaînes vides (''
), un format à longueur fixe est utilisé. Avec le format à longueur fixe, il n'y a plus besoin de délimiteurs. A la place, les colonnes et les lignes sont écrites en utilisant la taille d'affichage des colonnes. Par exemple, si une colonne est déclarée de type INT(7)
, les valeurs seront écrite en utilisant des colonne de 7 caractères. En lecture, les données sont obtenues en lisant 7 caractères. Les fichiers sans délimiteurs ont un impact sur la façon avec laquelle la valeur NULL
est enregistrée.
La gestion de la valeur NULL
dépends des options FIELDS
et LINES
utilisées :
FIELDS
and LINES
, NULL
est symbolisé par as \N
en lecture et en écriture. (en supposant que le caractère ESCAPED BY
est ``\'').
FIELDS ENCLOSED BY
n'est pas vide, un champs contenant littéralement la chaîne NULL
est utilisé, en écriture et en lecture. (Ceci est différent du mot 'NULL',
entouré de caractères FIELDS ENCLOSED BY
et lu comme la chaîne 'NULL'
).
FIELDS ESCAPED BY
est vide, NULL
est directement écrit NULL
.
FIELDS TERMINATED BY
et FIELDS ENCLOSED BY
sont tous les deux vides), NULL
s'écrit comme une chaîne vide. Il faut noter que cela entraîne l'identité de la valeur NULL
et des chaînes vides. Il ne sera alors pas possible d'en faire la différence.
Certains cas ne sont pas accepté par LOAD DATA INFILE
:
FIELDS TERMINATED BY
et FIELDS ENCLOSED BY
tous les deux vides) et des colonnes de type BLOB
ou TEXT
.
LOAD DATA INFILE
ne seront pas capable d'interpréter le fichier. Par exemple, le champs FIELDS
va poser problème:
FIELDS TERMINATED BY '"' ENCLOSED BY '"'
FIELDS ESCAPED BY
est vide, un champs qui contient une occurrence de FIELDS ENCLOSED BY
ou LINES TERMINATED BY
suivi FIELDS TERMINATED BY
va provoquer une erreur, et l'arret de la lecture du fichier. Ceci, car LOAD DATA INFILE
ne peut pas determiner correctement la fin de la valeur, ou du champs.
Les exemples suivants charge toutes les colonnes de la tables persondata
:
mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;
Aucun champs n'est précisé, alors LOAD DATA INFILE
s'attend à trouver une valeur pour chaque colonne. Les valeurs par défaut FIELDS
et LINES
sont supposés.
Pour ne charger qu'une partie des colonnes, on peut utiliser :
mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata (col1,col2,...);
Il faut aussi préciser la liste des champs dans l'ordre d'apparition de celles ci dans le fichier, surtout si elles apparaissent dans un autre ordre que celui de la table.
Si il manque des champs, les colonnes qui n'ont pas de valeurs seront mises à leur valeur par défaut. Les valeurs par défaut sont décrites dans la section CREATE TABLE
.
La valeur d'un champs vide est interprété différemment, suivant le champs manquant :
Les colonnes de type TIMESTAMP
prennent la valeur de l'heure et la date courante si une NULL
leur est affectée. ou (pour la première colonne de type TIMESTAMP
) si la colonne est omise de la liste de champs à lire.
Si une ligne à trop de champs, les champs supplémentaires sont ignorés, et le nombre d'alerte est augmenté.
LOAD DATA INFILE
considère toutes les valeurs en entrées comme des chaînes, donc il n'est pas possible d'utiliser les formes numériques, notamment pour les types ENUM
ou SET
. . Toutes les énumérations doivent être spécifiée comme des chaînes
Lors de l'utilisation de LOAD DATA INFILE
, la fonction mysql_info()
permet d'obtenir des informations sur la requête. Le format de la réponse est comme suite :
Records: 100 Duplicates: 0 Warnings: 0
Duplicates
indique le nombre de lignes qui n'a pas pus être insérées car elles tentaient de doubler une clé primaire.. Warnings
indique le nombre d'insertions qui ont générer une erreur lors de l'insertion. Warnings
surviennent lorsqu'il y a une tentative incorrecte d'insertion de ligne.
UPDATE
UPDATE [LOW_PRIORITY] nom_table SET nom_colonne1=expr1,nom_colonne2=expr2,... [WHERE where_definition] [LIMIT #]
UPDATE
met à jour une ligne éxistante dans une table. La clause SET
indique quelles colonnes modifier, et quelles valeurs mettre dans ces colonnes. La conditions WHERE
permet de choisir quelles lignes sont à mettre à jour. Sinon, toutes les lignes sont mises à jour
L'option LOW_PRIORITY
, permet de retarder l'exécution de la requête jusqu'au moment où il n'y a plus de client qui lisent la table
Lors de l'accès à une colonne de la table Nom_table
dans une expression, UPDATE
utilise la valeur courante de la colonne. Par exemple, la requête suivante ajoute 1 à la colonne age
.
mysql> UPDATE persondata SET age=age+1;
Les commandes UPDATE
sont évaluées de gauche à droite. Par exemple, la requête suivante double la colonne age
, puis l'incrémente d'une unité :
mysql> UPDATE persondata SET age=age*2, age=age+1;
Affecter la valeur courante d'une colonne lors d'une commande UPDATE
conduit MySQL à ignore cette mise à jour.
La commande UPDATE
retourne le nombre de ligne qui ont été effectivement modifiées.. A partir de MySQL 3.22, la fonction C API mysql_info()
nombre de ligne qui ont été trouvées et effectivement modifiées, puis le nombre de warnings de la commande UPDATE
.
USE
USE Nom_bdd
La commande USE Nom_bdd
statement indique à MySQL le nom de la base de données par défaut pour les requête suivantes. Cette base restera courante jusqu'à la fin de la session, ou jusqu'à la prochaine utilisation de la commande USE
:
mysql> USE db1; mysql> SELECT count(*) FROM maTable; # selects from db1.maTable mysql> USE db2; mysql> SELECT count(*) FROM maTable; # selects from db2.maTable
L'utilisation d'une base de données par défaut n'empêche pas l'accès aux autres bases. Par exemple, il est toujours possible d'accéder à la table editeur
de la base db2
, même après l'utilisation de USE db1
mysql> USE db1; mysql> SELECT author_name,editor_name FROM author,db2.editor WHERE author.editor_id = db2.editor.editor_id;
La commande USE
est fournie pour assurer la compatibilité avec Sybase.
FLUSH
(vider les caches)FLUSH flush_option [,flush_option]
La commande FLUSH
permet d'effacer les caches internes de MySQL uses. Pour l'exécuter, il faut avoir les droits de rechargement (reload ).
flush_option
peut prendre les valeurs suivantes :
Ces commandes sont disponibles avec l'utilitaire mysqladmin
, en utilisant les options flush-hosts
, flush-logs
, reload
ou flush-tables
.
KILL
KILL thread_id
KILL thread_id
Chaque connection à mysqld
génére un thread séparé. La liste des threads est accessible avec la SHOW PROCESSLIST
et la fonction KILL thread_id
, permet de terminer immédiatement ces threads.
Il faut avoir les droits de process pour voir et terminer tous les threads. Sinon, seul les threads utilisateurs sont visibles et terminables.
Ces commandes sont disponibles avec l'utilitaire mysqladmin
en utilisant les options mysqladmin processlist
and mysqladmin kill
.
SHOW
(Informations sur les tables, colonnes,...)SHOW DATABASES [LIKE wild] ou SHOW TABLES [FROM Nom_bdd] [LIKE wild] ou SHOW COLUMNS FROM Nom_table [FROM Nom_bdd] [LIKE wild] ou SHOW INDEX FROM Nom_table [FROM Nom_bdd] ou SHOW STATUS ou SHOW VARIABLES [LIKE wild] ou SHOW PROCESSLIST ou SHOW TABLE STATUS [FROM Nom_bdd] [LIKE wild]
SHOW
fourni les caractéristiques des bases de données, tables et colonnes sur le serveur. Si l'option LIKE wild
est utilisée, la chaîne wild
peut utiliser les caractères spéciaux ``%'' et ``_''.
Il y a deux possibilités pour référencer une table : Nom_bdd.Nom_table
ou Nom_table FROM Nom_bdd
syntax. Les deux requêtes suivantes sont équivalentes :
mysql> SHOW INDEX FROM maTable FROM maBase; mysql> SHOW INDEX FROM maBase.maTable;
SHOW DATABASES
fait la liste des bases de donnés sur le serveur MySQL. mysqlshow
fournit les mêmes renseignements.
SHOW TABLES
fait la liste des tables sur une base donnée. mysqlshow Nom_bdd
fournit les mêmes renseignements.
Note: Si un utilisateur n'a aucun droit pour une table, la table n'apparaitra pas dans les SHOW TABLES
ou mysqlshow Nom_bdd
.
SHOW COLUMNS
fait la liste des colonnes d'une table. Si les types des colonnes sont différens de ce qui ont été spécifiés à la création, avec la CREATE TABLE
, il faut savoir que parfois, MySQL change spontanément le type de colonnes. 7.6.1 Modifications automatiques de type de colonne.
La commande DESCRIBE
fournit les mêmes informations que SHOW COLUMNS
. DESCRIBE
.
SHOW TABLE STATUS
(nouveauté de la version 3.23) fonctionne comme SHOW STATUS
, mais fournit beaucoup plus d'informations sur chaque table. L'utilitaire mysqlshow
avec l'option --status Nom_bdd
effectue la même requête. Les colonnes suivantes sont renvoyées :
Name | Name of the table |
Type | Type of table (NISAM, MyISAM or HEAP) |
Rows | Number of rows |
Avg_row_length | Average row length |
Data_length | Length of the data file |
Max_data_length | Max length of the data file |
Index_length | Length of the index file |
Data_free | Number of allocated but not used bytes |
Auto_increment | Next autoincrement value |
Create_time | When the table was created |
Update_time | When the data file was last updated |
Check_time | When one last run a check on the table |
Create_options | Extra options used with CREATE TABLE
|
Comment | The comment used when creating the table (or some information why MySQL couldn't access the table information). |
SHOW FIELDS
est un synonyme de SHOW COLUMNS
et SHOW KEYS
est un synonyme de SHOW INDEX
Ces commandes sont disponibles avec l'utilitaire mysqlshow Nom_bdd Nom_table
ou mysqlshow -k Nom_bdd Nom_table
.
SHOW INDEX
retourne les informations dans un format proche de SQLStatistics
sous ODBC. Les informations suivantes sont disponibles :
Table | Name of the table |
Non_unique | 0 if the index can't contain duplicates. |
Key_name | Name of the index |
Seq_in_index | Column sequence number in index, starting with 1. |
Column_name | Column name. |
Collation | How the column is sorted in the index. In MySQL, this can have values A (Ascending) or NULL (Not sorted).
|
Cardinality | Number of unique values in the index. This is updated by running isamchk -a .
|
Sub_part | Number of indexed characters if the column is only partly indexed. NULL if the entire key is indexed.
|
SHOW STATUS fournit des informations sur le serveur (tout comme mysqladmin extended-status
). Les informations fournies sont présentées ci-dessous. Le format et les nombres peuvent varier :
+--------------------------+--------+ | Variable_name | Value | +--------------------------+--------+ | Aborted_clients | 0 | | Aborted_connects | 0 | | Created_tmp_tables | 0 | | Delayed_insert_threads | 0 | | Delayed_writes | 0 | | Delayed_errors | 0 | | Flush_commands | 2 | | Handler_delete | 2 | | Handler_read_first | 0 | | Handler_read_key | 1 | | Handler_read_next | 0 | | Handler_read_rnd | 35 | | Handler_update | 0 | | Handler_write | 2 | | Key_blocks_used | 0 | | Key_read_requests | 0 | | Key_reads | 0 | | Key_write_requests | 0 | | Key_writes | 0 | | Max_used_connections | 1 | | Not_flushed_key_blocks | 0 | | Not_flushed_delayed_rows | 0 | | Open_tables | 1 | | Open_files | 2 | | Open_streams | 0 | | Opened_tables | 11 | | Questions | 14 | | Running_threads | 1 | | Slow_requêtes | 0 | | Uptime | 149111 | +--------------------------+--------+
Les variables ci-dessus ont les significations suivantes :
Aborted_clients | Number of connections that has been aborted because the client has died without closing the connection properly. |
Aborted_connects | Number of tries to connect to the MySQL server that has failed. |
Created_tmp_tables | Number of implicit temporary tables that has been created while executing statements. |
Delayed_insert_threads | Number of delayed insert handler threads in use. |
Delayed_writes | Number of rows written with INSERT DELAYED .
|
Delayed_errors | Number of rows written with INSERT DELAYED for which some error occurred (probably duplicate key ).
|
Flush_commands | Number of executed FLUSH commands.
|
Handler_delete | Number of requests to delete a row from a table. |
Handler_read_first | Number of request to read first the row in a table. |
Handler_read_key | Number of request to read a row based on a key. |
Handler_read_next | Number of request to read next row in key order. |
Handler_read_rnd | Number of request to read a row based on a fixed position. |
Handler_update | Number of requests to update a row in a table. |
Handler_write | Number of requests to insert a row in a table. |
Key_blocks_used | The number of used blocks in the key cache. |
Key_read_requests | The number of request to read a key block from the cache. |
Key_reads | The number of physical reads of a key block from disk. |
Key_write_requests | The number of request to write a key block to the cache. |
Key_writes | The number of physical writes of a key block to disk. |
Max_used_connections | The maximum number of connections that has been in use simultaneously. |
Not_flushed_key_blocks | Keys blocks in the key cache that has changed but hasn't yet been flushed to disk. |
Not_flushed_delayed_rows | Number of rows waiting to be written in INSERT DELAY queues.
|
Open_tables | Number of tables that are open. |
Open_files | Number of files that are open. |
Open_streams | Number of streams that are open (used mainly for logging) |
Opened_tables | Number of tables that has been opened. |
Questions | Number of questions asked from to the server. |
Running_threads | Number of currently open connections. |
Slow_queries | Number of requêtesthat has taken more than long_query_time
|
Uptime | How many seconds the server has been up. |
Commentaires :
Opened_tables
est grand, alors table_cache
est probablement trop petit.
key_reads
est trop grand, alors key_cache
est probablement trop petit. Le taux d'accès au cache est calculé avec la key_reads
/key_read_requests
.
Handler_read_rnd
est grand, alors il y a probablement trop de requêtes qui obligent MySQL a scanner des tables entières, ou il y a des commandes join qui n'utilisent pas les clés à bon escient.
SHOW VARIABLES
affiche quelques variables système de MySQL. Cette commande est disponible avec l'utilitaire mysqladmin variables
command. Si les valeurs par défaut ne conviennent pas, il faut faire les réglages au démarrage, dans la commande de mysqld
. Les informations fournit sont les suivantes, et ressemble fort au tableau ci-dessous :
+------------------------+--------------------------+ | Variable_name | Value | +------------------------+--------------------------+ | back_log | 5 | | connect_timeout | 5 | | basedir | /my/monty/ | | datadir | /my/monty/data/ | | delayed_insert_limit | 100 | | delayed_insert_timeout | 300 | | delayed_queue_size | 1000 | | join_buffer_size | 131072 | | flush_time | 0 | | key_buffer_size | 1048540 | | language | /my/monty/share/english/ | | log | OFF | | log_update | OFF | | long_query_time | 10 | | low_priority_updates | OFF | | max_allowed_packet | 1048576 | | max_connections | 100 | | max_connect_errors | 10 | | max_delayed_threads | 20 | | max_heap_table_size | 16777216 | | max_join_size | 4294967295 | | max_sort_longueur | 1024 | | max_tmp_tables | 32 | | net_buffer_longueur | 16384 | | port | 3306 | | protocol-version | 10 | | record_buffer | 131072 | | skip_locking | ON | | socket | /tmp/mysql.sock | | sort_buffer | 2097116 | | table_cache | 64 | | thread_stack | 131072 | | tmp_table_size | 1048576 | | tmpdir | /machine/tmp/ | | version | 3.23.0-alpha-debug | | wait_timeout | 28800 | +------------------------+--------------------------+
SHOW PROCESSLIST affiche la liste des processus en ligne. Cette commande est aussi disponible avec la mysqladmin processlist
. Avec les droits de process, tous les threads sont visibles. Sinon, seuls les threads utilisateurs sont visibles . KILL
.
KILL
.
EXPLAIN
(Détails sur SELECT
)EXPLAIN SELECT select_options
L'option EXPLAIN
force MySQL à expliquer la façon avec laquelle il va traiter la requête SELECT
, en détaillant les opérations de regroupement.
Avec ces informations, il est possible de determiner les tables qui requièrent des indexes pour accélerer les SELECT
, ainsi que l'ordre optimal dans lequel les tables reseront regroupées. Pour obliger l'optimiseur à respecter l'ordre de regroupement, il suffit d'ajouter l'option STRAIGHT_JOIN
.
Pour les regroupements complexes, EXPLAIN
retourne une ligne d'informations pour chaque table utilisée par la commande SELECT
. Les tables sont listées dans l'ordre de lecture. MySQL résoud les regroupements en utilisant une méthode d'aggrégation en un seul passage. Cela signifie que MySQL lit une ligne de la première table, puis il recherche les lignes correspondantes dans la seconde table, et ainsi de suite jusqu'à la dernière table. Quand toutes les tables ont été traitées, il retourne la ligne selectionnée, et remonte progressivement jusqu'à la table initiale. Puis, la ligne suivante est selectionnée, et le processus continue avec la ligne suivante.
La réponse de EXPLAIN
inclus les colonnes suivantes :
table
La table qui est utilisée par la commande.
type
Le type de regroupement. Le détails sur les différents types est donnés plus bas.
possible_keys
Les possible_keys
indiques quels index MySQL peut utiliser pour rechercher des lignes dans la table. Si la colonne est vide, il n'y a pas d'index. Dans ce cas, il est surement possible d'améliorer les performances de la requête en éxaminant la clause WHERE
pour voir quelles colonnes sont utilisées, et quelles colonnes mériteraient un indexage. Dans ce cas, il suffit de créer l'index adéquat, et de reverifier la requête avec EXPLAIN
. Pour voir quels sont les index disponibles pour une table, il faut utiliser la commande SHOW INDEX FROM Nom_table
.
key
La colonne clé indique quelle clé MySQL a décidé d'utiliser. La clé est NULL
si aucun index n'est choisi.
key_len
key_len
indique la longueur de la clé que a décidé d'utiliser. La longueur sera NULL
si la clé est NULL
.
ref
ref
est le ou les numéros de colonne ou constantes utilisée avec la clé pour rechercher les lignes dans la table.
rows
rows
indique le nmbre de ligne que MySQL doit examiner pour éxécuter la requête.
Extra
Si la colonne inclus le texte Only index
, cela signifie que les informaions sont renvoyées par la table en utilisant uniquement l'index. Généralement, c'est beaucoup plus rapide que de scanner la table entière. Si cette colonne contient le texte where used
, cela signifie que la clause WHERE
a été utilisée pour restreindre le nombre de ligne à retourner au client.
Voici maintenant la liste des différents types de regroupement, du plus efficace au moins efficace :
system
La table n'a qu'une seule ligne (= table système). C'est un cas spécial de regroupement de type const
.
const
La table a au maximum une ligne à traiter, qui sera lue au début de la requête. Etant donné qu'il n'y a qu'une seule ligne, les valeurs de cette ligne peuvent être considérées comme des constantes pour l'optimisateur. Les tables de type const
sont extrêmement rapide à lire!
eq_ref
Une ligne sera lue de cette table pour chaque combinaisons de ligne des tables précédentes. C'est le meilleur type de regroupement possible, en dehors du type const
. Il sera utilissé lorsque toutes les colonnes d'un index sont utilisées par un regroupement, et que l'index est UNIQUE
ou PRIMARY KEY
.
ref
Toutes les lignes qui correspondent aux valeurs de l'index seront lues dans cette table, pour chaque combinaison de lignes des tables précédentes. ref
est utilisé si le regroupement utilise un préfixe comme clé, ou si la clé n'est pas UNIQUE
ou PRIMARY KEY
( en d'autres termes, si le regroupement ne peut pas sectionner une ligne unique à partir de la clé). Si la clé qui est utilisée ne rassemble que très peu de lignes, le regroupement est bon.
range
Seules les lignes dans l'intervalle considéré seront renvoyée, en utilisant un index pour selectionner les lignes. La colonne ref
indiquera quelles index sera utilisé.
index
Ce type est indentique à ALL
, sauf que seul l'index est scanné. C'est généralement plus rapide que le type ALL
, car un fichier d'index est généralement plus petit que le fichier de données.
ALL
Une recherche sur la table complète va être faite, pour chaque combinaison des tables précédentes. C'est généralement très mauvais si la première table n'est pas marquée const
, et encore plus mauvais dans les autres cas. On peut éviter d'utiliser ce mode de recherche en ajoutant des index, afin de transformer les lignes en constantes.
Un bon critère pour evaluer l'efficacité d'un regroupement est de multiplier toutes les valeurs dans la colonne rows
d'une requête avec EXPLAIN
. Cela mesure approximativement le nombre de ligne que MySQL doit examiner pour résoudre la requête. Ce nombre sera aussi utilisé pour restreindre la taille du regroupement, avec max_join_size
.
L'exemple suivant montre comme une clause peut être optimisée progressivement grÅce aux informations fournies par EXPLAIN
.
On supposera que l'on souhaite exécuter la commande SELECT
ci-dessous, et qu'on l'examine avec EXPLAIN
:
EXPLAIN SELECT tt.TicketNumber, tt.TimeIn, tt.ProjectReference, tt.EstimatedShipDate, tt.ActualShipDate, tt.ClientID, tt.ServiceCodes, tt.RepetitiveID, tt.CurrentProcess, tt.CurrentDPPerson, tt.RecordVolume, tt.DPPrinted, et.COUNTRY, et_1.COUNTRY, do.CUSTNAME FROM tt, et, et AS et_1, do WHERE tt.SubmitTime IS NULL AND tt.ActualPC = et.EMPLOYID AND tt.AssignedPC = et_1.EMPLOYID AND tt.ClientID = do.CUSTNMBR;
Pour cet exemple, on supposera par hypothèse :
Table | Column | Column type |
tt | ActualPC | CHAR(10)
|
tt | AssignedPC | CHAR(10)
|
tt | ClientID | CHAR(10)
|
et | EMPLOYID | CHAR(15)
|
do | CUSTNMBR | CHAR(15)
|
Table | Index |
tt | ActualPC
|
tt | AssignedPC
|
tt | ClientID
|
et | EMPLOYID (primary key)
|
do | CUSTNMBR (primary key)
|
tt.ActualPC
n'ont pas encore été assignées.
Au démarrage, avant la moindre optimisation, la clause produit la réponse suivante :
table type possible_keys key key_len ref rows Extra et ALL PRIMARY NULL NULL NULL 74 do ALL PRIMARY NULL NULL NULL 2135 et_1 ALL PRIMARY NULL NULL NULL 74 tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 range checked for each record (key map: 35)
Etant donné que le type de regroupement est ALL
pour toutes les tables, ces informations indique que MySQLfait un regroupement sur toutes les tables! Cela va prendre un temps énorme, vu le nombre de lignes à étudier dans chaque table. Pour le cas présent, cela représente 74 * 2135 * 74 * 3872 = 45,268,558,720
rows. Et encore, ces tables pourraient être encore plus grosses...
Un des problèmes posés ici est que MySQL ne peut pas encore (encore) utiliser d'index pour des colonnes déclarées de manière différentes. Dans l'exemple, VARCHAR
et CHAR
sont identiques, à moins qu'ils ne soient déclarés sur des longueurs différentes. Or, tt.ActualPC
est de type CHAR(10)
et et.EMPLOYID
est de type CHAR(15)
: les longueur ne concordent pas.
Pour consolider la base, on utilise la commande ALTER TABLE
pour rallonger le champs ActualPC
de 10 caractères à 15 caractères:
mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR(15);
Maintenant, tt.ActualPC
et et.EMPLOYID
sont tous les deux de type VARCHAR(15)
. L'éxecution de la commande EXPLAIN
produit maintenant le résultat suivant :
table type possible_keys key key_len ref rows Extra tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 where used do ALL PRIMARY NULL NULL NULL 2135 range checked for each record (key map: 1) et_1 ALL PRIMARY NULL NULL NULL 74 range checked for each record (key map: 1) et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1
Ce n'est pas parfait, mais c'est nettement mieux (le produit des colonnes rows
a été réduit d'un facteur 74). Cette version s'éxecute maintenant en quelques secondes.
Une autre amélioration peut être apportée en éliminant les disparités de longueur entre les colonnes tt.AssignedPC et et_1.EMPLOYID
, et d'autres part , tt.ClientID et do.CUSTNMBR
comparisons:
mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15), MODIFY ClientID VARCHAR(15);
Maintenant EXPLAIN
produit maintenant le résultat suivant :
table type possible_keys key key_len ref rows Extra et ALL PRIMARY NULL NULL NULL 74 tt ref AssignedPC,ClientID,ActualPC ActualPC 15 et.EMPLOYID 52 where used et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1 do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1
C'est déjà très bien.
Le problème final est que, par défaut, MySQL suppose que les valeurs dans la colonne tt.ActualPC
sont réparties uniformément. Or, ce n'est pas le cas de la table tt
. Heureusement, il est facile de le préciser à MySQL :
shell> isamchk --analyze PATH_TO_MYSQL_DATABASE/tt shell> mysqladmin refresh
Le résultat est maintenant parfait, et maintenant EXPLAIN
produit maintenant le résultat suivant :
table type possible_keys key key_len ref rows Extra tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 where used et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1 et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1 do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1
On peut noter que la colonne rows
est une estimation de la part de l'optimisateur de regroupement de MySQL : pour optimiser une commande, il faudrait maintenant vérifier qu'elle a des chiffres proche de la vérité. Si non, il faudrait améliorer les performances avec la clause STRAIGHT_JOIN
dans la commande SELECT
, et essayer de proposer différents ordres pour la liste des tables .
DESCRIBE
(Informations sur les colonnes){DESCRIBE | DESC} Nom_table {Nom_col | wild}
DESCRIBE
fournit des informations à propos des colonnes d'une table. Nom_col
peut être un nom de colonne, ou une chaîne qui contenant le caractère spécial SQL ``%'' et ``_'' .
DESCRIBE
fait la liste des colonnes d'une table. Si les types des colonnes sont différens de ce qui ont été spécifiés à la création, avec la CREATE TABLE
, il faut savoir que parfois, MySQL change spontanément le type de colonnes. 7.6.1 Modifications automatiques de type de colonne.
La commande USE
est fournie pour assurer la compatibilité avec Oracle.
La commande SHOW
fournit les mêmes informations. SHOW
.
LOCK TABLES/UNLOCK TABLES
LOCK TABLES Nom_table [AS alias] {READ | [LOW_PRIORITY] WRITE} [, Nom_table {READ | [LOW_PRIORITY] WRITE} ...] ... UNLOCK TABLES
LOCK TABLES
verrouille une table dans le thread courant. UNLOCK TABLES
ouvre tous les verrous posé par le thread courant. Toutes les tables verrouillé par un thread sont automatiquement déverrouillée quand le thread émet un autre LOCK TABLES
, ou à la fin de la connexion au serveur.
Si un thread obtiens le verrou de lecture (READ
) sur une table, le thread (et tous les autres threads) ne peut que lire dans la table. Si un thread obtiens e verrou de lecture (READ
) sur une table, le thread qui a le verrous est le seul à pouvoir lire ou écrire dans la table.
Les autres threads attendent (sans limite) que le verrous se libère.
Le verrous d'écriture a une priorité supérieure au verrou de lecture, afin que les processus de mise à jour puisse se faire dès que possible. Cela signifie que si un thread obtiens un verrou de lecture, et qu'un autre thread obtiens un verrou d'écriture, alors le thread au verrou de lecture devra attendre la libération du verrou d'écriture. Il est possible d'utiliser des verrous d'écriture de basse priorité (LOW_PRIORITY WRITE
), mais il faut être sur qu'il y aura un moment ou aucun thread ne sera en train de lire la table.
Lors de l'utilisation de la commande LOCK TABLES
, il faut verrouiller toutes les tables qui vont être utilisées. Si il y a des alias dans une requête, il faut aussi avoir les verrous pour les alias! Cette politique assure que la table ne se verrouille jamais, sans pouvoir être déverrouillée.
Il ne faut jamais verrouiller une table qui va accepter une insertion reportée (INSERT DELAYED)
. Car, dans ce cas, l'insertion sera faite dans un autre thread, qui n'aura pas le verrou.
Généralement, il n'y a pas besoin de verrouiller les tables, car les mise à jour UPDATE
sont atomiques : aucun autre thread ne peut interférer avec la commande en cours d'éxécution. Il y a toutes fois, quelques cas où il est bon de verrouiller une table :
SELECT
et une commande UPDATE
. L'exemple ci-dessous montre comment exécuter une transaction :
mysql> LOCK TABLES trans READ, customer WRITE; mysql> select sum(value) from trans where customer_id= some_id; mysql> update customer set total_value=sum_from_previous_statement where customer_id=some_id; mysql> UNLOCK TABLES;
Sans la commande LOCK TABLES
, il se peut qu'un autre thread insère une nouvelle ligne dans la table trans
entre les deux commandes SELECT
et UPDATE
.
En utilisant des modifications incrémentales (UPDATE customer SET value=value+new_value
) ou avec la commande LAST_INSERT_ID()
, on peut généralement éviter l'utilisation des LOCK TABLES
.
Il est aussi possible de résoudre quelques cas en utilisant les verrous utilisateurs GET_LOCK()
et RELEASE_LOCK()
. Ces verrous sont sauvés dans une table du serveur, et programmé avec pthread_mutex_lock()
et pthread_mutex_unlock()
pour plus de rapidité.n Miscellaneous functions
.
10.11 Comment MySQL verrouille les tables.
SET OPTION
SET [OPTION] SQL_VALUE_OPTION= value, ...
SET OPTION
selectionne différentes options qui affecteront le mode opératoire du client ou du serveur. Toute option reste valable jusqu'à la fin de la session, ou jusqu'à la prochaine modification.
CHARACTER SET character_set_name | DEFAULT
Cette option permet de choisir la table des caractères utilisée par MySQL. Actuellement, la seule option possible est cp1251_koi8
, mais il est très simple d'ajouter de nouvelles tables en éditant le fichier ``sql/convert.cc'' dans le code source de MySQL . La table par défaut peut être rappelée en utilisant la valeur DEFAULT
. Il faut noter que la syntaxe pour choisir la table de caractère est différente des autres.
PASSWORD = PASSWORD('some password')
Choisit un nouveau mot de passe pour l'utilisateur courant. Tout utilisateur non-anonyme peut changer son mot de passe!
PASSWORD FOR user = PASSWORD('some password')
Assigne un nouveau mot de passe pour un utilisateur du serveur courant. Seul, un utilisateur avec des droits d'accès à mysql
database peut le faire. L'utilisateur modifié doit être désigné par utilisateur@nom_hote
, avec utilisateur
et nom_hote
qui prennent les valeurs qui apparaissent dans la tablemysql.user
, sous les colonnes User
et Host
columns of the table entry. Par exemple, si il existe une ligne avec User
et Host
qu valent respectivement 'bob'
et '%.loc.gov'
, il faudra écrire:
mysql> SET PASSWORD FOR bob@"%.loc.gov" = PASSWORD("newpass");
SQL_BIG_TABLES = 0 | 1
Si mis à un, toutes les tables temporaires sont stockés sur le disque dur, plutôt qu'en mémoire. Cela rend le processus un peu plus lent, mais il génère pas d'erreur du type The table Nom_table is full
(la table Nom_table est pleine), si de grosses commandes SELECT
demandes de grandes tables temporaires. Par défaut, cette option est à 0.
SQL_BIG_SELECTS = 0 | 1
Si mis à 1
, MySQL annulera une commande SELECT
qui va prendre un temps trop long. Ceci est très utile quand une clause WHERE
complexe a été spécifiée. Une requête trop long est une commande SELECT
qui va avoir à étudier plus de max_join_size
rows lignes. Par défaut, cette valeur est à 0 (Toutes les commandes SELECT
autorisées).
SQL_LOW_PRIORITY_UPDATES = 0 | 1
Si mis à 1
, toutes les commandes INSERT
, UPDATE
et DELETE
attendent qu'il n'y ait plus de commande SELECT
en attente sur la table affectée.
SQL_SELECT_LIMIT = value | DEFAULT
Le nombre maximal de ligne à retourner dans une commande SELECT
. Si une commande SELECT
a une clause de limite LIMIT
, LIMIT
est prioritaire sur SQL_SELECT_LIMIT
. La valeur par défaut pour cette option est "sans limite". Si la limite a été changée, il est toujours possible de restaurer la configuration initiale avec DEFAULT
.
SQL_LOG_OFF = 0 | 1
Si mis à 1
, aucun historique ne sera transmis au client, si le client a les droits de process . Ceci n'affecte pas l'historique de mise à jour.
SQL_LOG_UPDATE = 0 | 1
Si mis à 0
, aucun historique de modification ne sera tenu, si le client a les droits de process privilege. Ceci n'affecte pas l'historique du client.
TIMESTAMP = timestamp_value | DEFAULT
Met à l'heure le client. Cette fonction est généralement utilisée pour fixer la valeur initiale du timestamp, lors de l'utilisation de l'historique pour recréer des lignes.
LAST_INSERT_ID = #
Fixe la valeur qui sera retournée par la prochaine fonction LAST_INSERT_ID()
. Elle est stockée dans l'historique de modification.
INSERT_ID = #
Fixe la prochaine valeur à utiliser lors d'une insertion dans une table avec une colonne de type AUTO_INCREMENT
value. Cela sert surtout avec l'historique de modifications.
GRANT
et REVOKE
GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...] ON {Nom_table | * | *.* | Nom_bdd.*} TO user_name [IDENTIFIED BY 'password'] [, user_name [IDENTIFIED BY 'password'] ...] [WITH GRANT OPTION] REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...] ON {Nom_table | * | *.* | Nom_bdd.*} FROM user_name [, user_name ...]
GRANT
est implémenté depuis la version 3.22.11de MySQL. Pour les ancienne versions, la commande GRANT
ne fait rien.
Les commandes GRANT
et REVOKE
permettent aux administrateurs système de donner et enlever des droits aux utilisateurs :
mysql.user
.
mysql.db
et mysql.host
.
mysql.tables_priv
.
mysql.columns_priv
.
Les commandes GRANT
et REVOKE
peuvent s'appliquer aux droits suivants, précisés dans priv_type
:
ALL PRIVILEGES FILE RELOAD ALTER INDEX SELECT CREATE INSERT SHUTDOWN DELETE PROCESS UPDATE DROP REFERENCES USAGE
ALL
est un synonyme de for ALL PRIVILEGES
. REFERENCES
n'est pas encore implémenté. USAGE
est actuellement synonyme de ``aucun droits''.Il peut être utilisé pour créer un utilisateur sans droits.
Pour enlever le droit de grant d'un utilisateur, il faut utiliser la valeur suivante dans priv_type
:
REVOKE GRANT OPTION ON ... FROM ...;
Les seules valeurs de priv_type
qu'il est possible de spécifier sont SELECT
, INSERT
, UPDATE
, DELETE
, CREATE
, DROP
, GRANT
, INDEX
et ALTER
.
Les seules valeurs de priv_type
qu'il est possible de spécifier pour une colonne (c'est à dire, en utilisant la clause column_list
) sont SELECT
, INSERT
et UPDATE
.
Il est possible de donner les droits généraux en utilisant la syntaxe ON *.*
. Il est possible de donner des droits sur une base de données en utilisant la syntaxe ON Nom_bdd.*
syntax. Si il y a une base de données courante, et que l'on spécifie ON *,
cela revient à donner tous les droits pour la base de données courante
. (Attention: Si il n'y a pas de base de données courante, cela revient à donner des droits sur le serveur entier! )
Afin de pouvoir donner des droits à des utilisateurs d'hotes divers et variés, MySQL accepte la spécification de l'utilisateur sous la forme user@host
. Pour pouvoir spécifier des noms d'utilisateur ou d'hotes ayant des caractères spéciaux dans le nom (comme ``-''), il suffit d'entourer le nom de l'utilisateur ou de l'hote de guillemets simples (i.e., 'test-user''test-hostname'
).
Les noms d'hotes peuvent avoir des caractères jokers : Par exemple, user@"%.loc.gov"
s'applique à tous les utilisateurs user
pour tous les hotes du domaine loc.gov
et user@"144.155.166.%"
s'appliquera à tous les user
pour des hotes dans le domaine 144.155.166
.
La forme simplifié user
est un synonyme de user@"%"
. Note: pour autoriser des utilisateurs anonymes sur le serveur MySQL (ce qui est le comportement par défaut), il faut aussi ajouter les utilisateurs locaux, grÅce à la forme user@localhost
car sinon, la ligne pour l'utilisateur anonyme dans la table mysql.user
sera utilisée quand l'utilisateur essaiera de se connecter à MySQL depuis la machine locale! Les utilisateurs anonymes sont définis en insérant une ligne User=''
dans la table mysql.user
. On peut vérifier si cela s'applique en exécutant la ligne suivante :
mysql> SELECT Host,User FROM mysql.user WHERE User='';
Pour le moment, la commande GRANT
n'accepte que des hotes, tables, bases et colonnes dont le nom ne dépasse pas 60 caractères. Un nom d'utilisateur peut aller jusqu'à 16 caractères.
Les privilèges pour une table ou une colonne sont constitués du OU logique de chacun des droits. Par exemple, si la table mysql.user
précise que un utilisateur a un droit de select gloabal, cela ne peut pas être interdit par une entrée dans une base, une table ou une colonne.
Les droits pour une colonne sont calculés comme suit :
global privileges OR (database privileges AND host privileges) OR table privileges OR column privileges
Dans la plupart des cas, les droits sont donnés aux utilisateurs avec les niveaux de droits, ce qui simplifie grandement la vie.
Si des droits sont donnés à un couple user/hostname qui n'existe pas dans la table mysql.user
, une entrée est insérée dans la table des droits, et elle reste valide jusqu'à ce qu'une commande DELETE
l'efface. En d'autres termes, GRANT
peut créer un utilisateur, mais REVOKE
ne l'effacera pas. Il faut le faire explicitement avec DELETE
.
A partir de MySQL 3.22.12 , lors de la création d'un nouvel utilisateur ou avec les droits globaux, un mot de passe sera affecté avec la clause IDENTIFIED BY
. Si l'utilisateur à déjà un mot de passe, il sera remplacé par le nouveau.
Attention: Lors de la création d'un utilisateur, il aucun mot de passe n'est spécifiée, cet utilisateur n'aura pas de mot de passe. C'est très imprudent.
Les mots de passe peuvent être assignés et modifiés avec la commande : SET PASSWORD
. SET OPTION
.
Lors de l'attribution de droit de niveau base , une entrée est ajoutée dans la table mysql.db
, si nécessaire. Quand toutes les privilèges poue la base de données sont supprimés avec REVOKE
, l'entrée est effacée.
Si un utilisateur n'a aucun droit sur uen table, la table n'est pas affichée quand l'utilisateur fait une requête sur cette table. La table ne sera même pas visible avec une commandes SHOW TABLES
.
La clause WITH GRANT OPTION
donne à l'utilisateur la capacité de donner à d'autres utilisateurs des droits, d'un niveau égal à ceux qu'il a déjà. Il faut être très prudent quand on attribue ce droit, car deux utilisateurs avec des droits différents peuvent rassembler leurs droits.
Il faut bien savoir que lorsqu'on donne à un utilisateur le droit de grant, tous les droits que possède cet utilisateur sont transmissible par cet utilisateur. Supposons que l'on ait donné des droits d'insertion à un utilisateur. Si on lui ajoute le droit de select sur une base, et qu'on lui ajoute en plus WITH GRANT OPTION
, l'utilisateur peut donner les droits de selection et d'insertion à tout autre utilisateur. Et si on lui ajoute encore le droit de update, il pourra aussi donner ce droit.
Il ne vaut mieux pas donner des droits de alter à un utilisateur normal. Dans ce cas, l'utilisateur peut essayer de pirater le système en renommant les tables de droits du système.
Lors de l'utilisation des droits de table ou de colonne pour un utilisateur, le serveur examine les droits de table et de colonne pour tous les utilisateurs, et cela ralentit légérement MySQL.
Quand mysqld
démarre, tous les droits sont chargés en mémoire. Les droits de table, base et colonnes prennent effet aussitôt, et les droits d'utilisateur prennent effet à la première connexion. Les modifications des tables de droits sont faites avec les fonctions GRANT
et REVOKE
et sont repercutées par le serveur immédiatement.Si les tables de droits sont modifiées à la main (avec INSERT
, UPDATE
, etc.), il faut exécuter une commande FLUSH PRIVILEGES
ou lancer l'utilitaire mysqladmin flush-privileges
pour faire prendre en compte des nouveaux droits.
Les différences les plus notables entre ANSI SQL et MySQL pour la commande GRANT
sont:
REVOKE
ou en manipulant (avec précautions) les tables de droits.
CREATE INDEX
CREATE [UNIQUE] INDEX Nom_indexON Nom_table (Nom_col[(longueur]),... )
The CREATE INDEX
n'est disponible qu'à partir de la version 3.22. CREATE INDEX
est un raccourci de ALTER TABLE
qui crée des index. ALTER TABLE
Généralement, il est possible de créer des tous les index d'une table au moment de la création de la table, avec CREATE TABLE
. CREATE TABLE
CREATE INDEX
permettra alors d'ajouter de nouveaux index.
Une liste de nom de colonne de format (col1,col2,...)
créer un index de multiples colonnes. Les index sont formés en concaténant les différentes valeurs en une ligne.
Pour les valeurs de type CHAR
et VARCHAR
, les index peuvent ne prendre en compte qu'une partie de la colonne, en précisant Nom_col(longueur)
. (Avec les types BLOB
et TEXT
, cette longueur est obligatoire. ). La commande suivante montre comment créer un index sur les 10 premiers caractères d'une colonne :
mysql> CREATE INDEX part_of_name ON customer (name(10));
Etant donné que la plus part des mots diffèrent les uns des autres dans les 10 premières lettres, l'index crée ne devrait pas être moins efficace que la colonne, tout en étant nettement plus rapide. Faire des index à valeur partiel permet de réduire la taille des index, et d'accélérer les opération de tris et d'insertion.
Il faut noter que l'on peut ajouter à un index une colonne qui accepte les types NULL
, que depuis la version 3.23.2 de MySQL. De même pour les colonnes de type BLOB
/TEXT
. Cela impose l'utilisation du format de table MyISAM
.
DROP INDEX
DROP INDEX Nom_index
The DROP INDEX
n'est disponible qu'à partir de la version 3.22. DROP INDEX
est un raccourci de ALTER TABLE
qui efface des index. ALTER TABLE
ALTER TABLE
.
Le serveur MySQL accepte les commentaires qui commencent par # jusqu'à la fin de la ligne, et les commentaires multi-lignes de type C/C++ /*........... */
:
mysql> select 1+1; # This comment continues to the end of line mysql> select 1 /* this is an in-line comment */ + 1; mysql> select 1+ /* this is a multiple-line comment */ 1;
Bien que le serveur comprennent les commentaires multi lignes, il y a quelques restrictions :
mysql
, l'invite de commande passe de mysql>
à '>
or ">
.
Ces limitations s'applique aussi bien lors de l'utilsation de mysql
que lors de la lecture d'un fichier dans une table.
MySQL n'accepte pas les commentaires de type ``--'' ANSI SQL. 5.3.7 `--' comme début de commentaire.
CREATE FUNCTION/DROP FUNCTION
CREATE FUNCTION function_name RETURNS {STRING|REAL|INTEGER} SONAME shared_library_name DROP FUNCTION function_name
Une fonction définie par l'utilisateur est un bon moyen d'ajouter de nouvelles fonctionnalités à MySQL avec de nouvelles fonctions natives, comme par exemple ABS()
et CONCAT()
.
CREATE FUNCTION
sauve le nom de la fonction, le type et le point d'entrée de la fonction dans la table système mysql.func
. Il faut avoir les droit insert et delete pour pouvoir créer et effacer des fonctions.
Toutes les fonctions actives sont rechargées à chaque démarrage du serveur, à moins de lancer mysqld
avec l'option --skip-grant-tables
. Dans ce cas, l'initialisation des fonctions utilisateurs est oubliée, et les fonctions sont inutilisables. (Une fonction active est une fonction créée par CREATE FUNCTION
et pas effacée avec DROP FUNCTION
.)
Un problème commun est la création d'une table avec des noms de colonne qui sont aussi des nom de type de données, ou de fonction natives MySQL. Ceci est parfaitement possible (par exemple, ABS
peut être un nom de colonne), mais aucun espace n'est autorisé entre le nom d'une fonction est la parenthèse ouvrante lorsque ces noms sont utilisé comme des fonctions .
Les mots suivants sont explicitement reservés par MySQL. La plus part sont interdits pas ANSI SQL92 comme nom de colonne ou nom de table (par exemple, group). Quelques uns sont reservés par MySQL qui en a besoin pour utiliser un analyseur syntaxique yacc
Les noms suivants (issus de la table ci-dessus) sont interdits pas ANSI SQL, mais acceptés apr MySQL comme nom de table/colonne. Ceci, car ces noms sont très courants, et de nombreuses personnes les utilisent déjà :
action | add | all | alter
|
after | and | as | asc
|
auto_increment | between | bigint | bit
|
binary | blob | bool | both
|
by | cascade | char | character
|
change | check | column | columns
|
constraint | create | cross | current_date
|
current_time | current_timestamp | data | database
|
databases | date | datetime | day
|
day_hour | day_minute | day_second | dayofmonth
|
dayofweek | dayofyear | dec | decimal
|
default | delete | desc | describe
|
distinct | distinctrow | double | drop
|
escaped | enclosed | enum | explain
|
exists | fields | first | float
|
float4 | float8 | foreign | from
|
for | full | function | grant
|
group | having | hour | hour_minute
|
hour_second | ignore | in | index
|
infile | insert | int | integer
|
interval | int1 | int2 | int3
|
int4 | int8 | into | if
|
is | join | key | keys
|
last_insert_id | leading | left | like
|
lines | limit | load | lock
|
long | longblob | longtext | low_priority
|
match | mediumblob | mediumtext | mediumint
|
middleint | minute | minute_second | month
|
monthname | natural | numeric | no
|
not | null | on | option
|
optionally | or | order | outer
|
outfile | partial | password | precision
|
primary | procedure | processlist | privileges
|
quarter | read | real | references
|
rename | regexp | reverse | repeat
|
replace | restrict | returns | rlike
|
second | select | set | show
|
smallint | soname | sql_big_tables | sql_big_selects
|
sql_select_limit | sql_low_priority_updates | sql_log_off | sql_log_update
|
straight_join | starting | status | string
|
table | tables | terminated | text
|
time | timestamp | tinyblob | tinytext
|
tinyint | trailing | to | use
|
using | unique | unlock | unsigned
|
update | usage | values | varchar
|
variables | varying | varbinary | with
|
write | where | year | year_month
|
zerofill
|
Les valeurs suivantes issues de la table ci dessus) sont interdites par ANSI SQL, mais autorisées par MySQL comme nom de table ou de colonne. Ceci, car ce sont des noms naturels, et de nombreuses personnes les utilisent déjà.
ACTION
BIT
DATE
ENUM
NO
TEXT
TIME
TIMESTAMP
Ce chapitre est une introduction à MySQL qui montre comment utiliser le client mysql
pour créer et utiliser une base de données simple. mysql
est un client (parfois appelée ``terminal'' ou aussi ``moniteur'') qui permet à un utilisateur de se connecter à un serveur MySQL, de lancer quelques requêtes, et de voir les résultats. mysql
peut aussi être lancé en mode automatique, en lui précisant un fichier qui contient les commandes à exécuter. Cette présentation de mysql
couvre les deux aspects.
Pour avoir la liste des options disponibles sur mysql
, il suffit d'utiliser l'option : --help.
shell> mysql --help
Ce chapitre supposera que mysql
est installé sur votre machine, et qu'un serveur MySQL est accessible. Si ce n'est pas le cas, contactez votre administrateur MySQL (Si vous etes l'administrateur, vous aurez certainement besoin de consulter d'autres sections de ce manuel).
Ce chapitre couvre la constitution et l'utilisation d'une base de données. Si vous êtes simplement interessé par la lecture de bases de données déjà existantes, vous pouvez éviter les premières sections qui montre la création d'une base de données et de tables.
Etant donné que ce chapitre n'est qu'un exemple d'introduction, de nombreux détails sont laissés de coté. N'hésitez pas à vous reportez aux autres sections du manuel, pour toute information complémentaire.
Pour se connecter au serveur MySQL, il vous faut un nom d'utilisateur, et, le plus probablement, un mot de passe. Si le serveur tourne sur une autre machine, il vous faudra aussi un nom d'hote. Contactez l'administrateur de la machine pour connaître les paramètres de connexion (i.e. le nom d'hote, le nom d'utilisateur, et le mot de passe). Une fois que vous connaîtrez tous ces paramètres, vous pourrez vous connecter comme ceci :
shell> mysql -h host -u user -p Enter password: ********
Les ********
représentent votre mot de passe : saisissez le lorsque mysql
affiche the Enter password (Entrez votre mot de passe):
invite.
Si tout a bien fonctionné, vous devriez voir s'afficher des informations d'introduction, suivies d'une invite de commande : mysql>
prompt:
shell> mysql -h host -u user -p Enter password: ******** Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 459 to server version: 3.22.20a-log Type 'help' for help. mysql>
L'invite de commande vous indique que mysql
est prêt à recevoir des commandes.
Certaines installations de MySQL permettent l'accès anonyme au serveur. Si c'est le cas de votre machine, vous devriez pouvoir vous connecter sans fournir aucune information.
shell> mysql
Après s'être correctement connecté, vous pouvez vous déconnecter à tout moment, en tapant QUIT
à l'invite de mysql.
mysql> QUIT Bye
Vous pouvez aussi vous déconnecter en tapant les touches contrôle-D.
Par la suite, nous supposerons que vous vous êtes correctement connecté au serveur.
Assurez vous que vous êtes correctement connecté. Dans le cas contraire, reportez vous à la section précédente. Ce faisant, vous ne vous êtes en fait connecté à aucune base de données, mais c'est bien comme ça. A ce stade ; il est important de savoir comment envoyer une requête, avant de savoir créer une table, charger des données, et interroger la base. Cette section décrit les principes de base de saisie des commandes, en utilisant des commandes qui vous familiariseront avec le fonctionnement de MySQL
.
Voici une commande simple qui demande au serveur la version et la date courante. Saisissez la comme ci-dessous, puis appuyez sur la touche entrée.
mysql> SELECT VERSION(), CURRENT_DATE; +--------------+--------------+ | version() | CURRENT_DATE | +--------------+--------------+ | 3.22.20a-log | 1999-03-19 | +--------------+--------------+ 1 row in set (0.01 sec) mysql>
Cette première requête montre beaucoup de caractéristiques de mysql
Une commande consiste généralement d'une commande SQL, suivie d'un point-virgule (Il y a quelques exceptions, ou les point-virgules ne sont pas nécessaires, comme la commande QUIT
, vue précédement. Nous y reviendrons plus loin).
Quand une requête a été saisie, mysql
l'envoie au serveur pour qu'il l'exécute, puis affiche le résultat, et repropose une nouvelle invite de commande : mysql>.
Mysql>
affiche la réponse du serveur sous forme de table (lignes et colonnes). La première ligne contient les titres des colonnes. Les lignes suivantes présentent les résultats de la requête. Généralement, les noms de colonnes sont les noms des colonnes des tables utilisées. Si la valeur retournée est une expression plutôt qu'une table, (comme dans l'exemple ci-dessus), mysql
crée une colonne avec comme titre l'expression évaluée.
mysql
affiche le nombre de ligne retourné, et le temps de traitement de la requête, ce qui donne une idée de la performance globale du serveur. Ces valeurs sont imprécises, car elle représente le temps passé entre l'envoi de la commande et la réception de la réponse, et ne montre pas quelle quantité de processeur a été utilisée. Cela ne permet pas de connaître la charge du serveur, ou les retards du réseau.
Par un souci de concision, la ligne ``rows in set'' ne sera plus affichée dans les exemples ultérieurs.
Les mots clés du langage peuvent être en majuscule ou minuscule, au choix. Les lignes suivantes sont équivalentes :
mysql> SELECT VERSION(), CURRENT_DATE; mysql> select version(), current_date; mysql> SeLeCt vErSiOn(), current_DATE;
Voici une autre requête qui montre que mysql
peut être utilisé comme une simple calculatrice.
mysql> SELECT SIN(PI()/4), (4+1)*5; +-------------+---------+ | SIN(PI()/4) | (4+1)*5 | +-------------+---------+ | 0.707107 | 25 | +-------------+---------+
Les commandes que nous venons de voir sont relativement courtes, et tiennent sur une seule ligne. Il est possible de saisir plusieurs commandes sur une seule ligne, il suffit de toujours les terminer par des points-virgules.
mysql> SELECT VERSION(); SELECT NOW(); +--------------+ | version() | +--------------+ | 3.22.20a-log | +--------------+ +---------------------+ | NOW() | +---------------------+ | 1999-03-19 00:15:33 | +---------------------+
Une commande n'est pas obligatoirement sur une seule ligne : les commandes les plus longues peuvent tenir sur plusieurs lignes. Ce n'est pas un problème, car mysql
détermines la fin de la commandes grÅce au point-virgule, et non pas en cherchant la fin de la ligne (en d'autres termes, mysql
accepte n'importe quel format de colonne, mais ne les exécute que si il trouve un point-virgule à la fin de la commande).
Voici une commande simple, et multi-lignes :
mysql> SELECT -> USER() -> , -> CURRENT_DATE; +--------------------+--------------+ | USER() | CURRENT_DATE | +--------------------+--------------+ | joesmith@localhost | 1999-03-18 | +--------------------+--------------+
Dans cet exemples, vous avez pu remarquer que l'invite passe de mysql>
à ->
dès que la commande devient multi-lignes. C'est par ce biais que mysql
indique qu'il n'a pas trouvé une commande complète, et qu'il attend un complément d'information. En observant bien l'invite de commande, vous saurez toujours ce que mysql
attend de vous.
Pour annuler une commande qui est partiellement saisie, il suffit de taper '\c' (slash-c)
mysql> SELECT -> USER() -> \c mysql>
Ici, l'invite de commande reprend son aspect initial. Cela indique que mysql
est prêt pour une nouvelle commande.
La table suivante montre les différentes formes de l'invite de commande, et sa signification :
Une commande peut s'étendre sur plusieurs lignes si, par accident, vous oubliez de terminer votre ligne par un point-virgule. Dans ce cas, mysql
attend plus d'informations :
mysql> SELECT USER() ->
Si cela vous arrive (vous pensez avoir entré une commande, mais la seule réponse est cette désespérante invite ->
) ; le plus souvent mysql
attends le point-virgule. Si vous ne comprenez pas que mysql
attend la suite de votre commande, vous risquez d'attendre un bon moment. Il suffit alors de compléter la commande avec un point-virgule, pour valider la commande.
mysql> SELECT USER() -> ; +--------------------+ | USER() | +--------------------+ | joesmith@localhost | +--------------------+
Les formes '>
et ">
d'invite de commande apparaissent lors de la saisie de chaînes. Avec MySQL, vous pouvez écrire des chaînes avec les guillemets simples et doubles : ``''' ou ``"' ; 'comme par exemple 'bonjour'
ou "au revoir"
. '>
et ">
signifie donc que vous avez commencé à saisir une chaîne de caractères, mais que vous n'avez pas encore fini. Si vous saisissez une chaîne de plusieurs lignes, c'est une indication judicieuse, mais est-ce souvent le cas? En général, ces deux invites de commande indiquent que vous avez oublié de refermer les guillemets :
mysql> SELECT * FROM my_table WHERE nom = "Smith AND age < 30; ">
Si vous saisissez cette commande SELECT
, puis tapez ENTREE, il ne va rien se passer. Plutôt que de se demander " mais qu'est ce qui prend tant de temps ", il vaut mieux remarquer que l'invite a pris la forme particulière de ">
. Cela signifie que mysql
s'attend ce que vous complétiez votre chaîne et la commande. En effet, la chaîne "Smith
n'a pas de deuxième guillemet.
A ce moment, que faire ? La chose la plus simplet d'annuler la commande. Cependant, vous ne pouvez pas taper \c
, car mysql
l'interprétera comme un caractère de chaîne. A la place, il faut clore la chaîne, puis taper \c
.
mysql> SELECT * FROM my_table WHERE nom = "Smith AND age < 30; "> "\c mysql>
L'invite de commande redevient mysql>
, ce qui indique que mysql
est prêt pour une nouvelle commande.
Il est important que les invites de commande de la forme signifie '>
et ">
que vous n'avez pas terminé une chaîne, et que toutes les lignes suivantes seront ignorées par l'analyseur de mysql
– y compris la commande QUIT
! Cela peut être déroutant, surtout si vous ne savez pas qu'il faut absolument fournir un guillemet de fin, même pour annuler la saisie
Voici quelques exemples de requêtes classiques avec MySQL.
Certains des exemples utilisent la table 'shop' qui contient les prix de chaque article (numéro d'objet). Supposons que chaque objet a un prix unique, et que le couple (item, trader) et une clé prmiaire pour ces lignes.
Vous pouvez créer cet exemple avec la table suivante :
CREATE TABLE shop ( article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL, dealer CHAR(20) DEFAULT '' NOT NULL, price DOUBLE(16,2) DEFAULT '0.00' NOT NULL, PRIMARY KEY(article, dealer)); INSERT INTO shop VALUES (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),(3,'C',1.69), (3,'D',1.25),(4,'D',19.95);
Les données pour l'exemple sont :
SELECT * FROM shop +---------+--------+-------+ | article | dealer | price | +---------+--------+-------+ | 0001 | A | 3.45 | | 0001 | B | 3.99 | | 0002 | A | 10.99 | | 0003 | B | 1.45 | | 0003 | C | 1.69 | | 0003 | D | 1.25 | | 0004 | D | 19.95 | +---------+--------+-------+
"Quel est le plus grand numéro d'objet?"
SELECT MAX(article) AS article FROM shop +---------+ | article | +---------+ | 4 | +---------+
"Retrouver le prix, le vendeur et le numéro de l'objet le plus cher du magasin"
En ANSI-SQL cela est très facilement fait avec un sous selection :
SELECT article, dealer, price FROM shop WHERE price=(SELECT MAX(price) FROM shop)
Avec MySQL (et donc, sans les sous selections), il faut le faire en deux étapes :
SELECT
.
SELECT article, dealer, price FROM shop WHERE price=19.95
Une autre solution est de trier les objets par prix, et de lire la première ligne, avec la clause MySQL LIMIT
:
SELECT article, dealer, price FROM shop ORDER BY price DESC LIMIT 1
Note: Avec cette méthode, on ne verra qu'ne seul objet, même si il y a plusieurs objets de meme prix.
"Quel est le prix maximal d'un article?"
SELECT article, MAX(price) AS price FROM shop GROUP BY article +---------+-------+ | article | price | +---------+-------+ | 0001 | 3.99 | | 0002 | 10.99 | | 0003 | 1.69 | | 0004 | 19.95 | +---------+-------+
"Pour chaque article, trouver le vendeur le plus cher."
En ANSI SQL
on pourrai le faire avec une sous selection, comme ceci :
SELECT article, dealer, price FROM shop s1 WHERE price=(SELECT MAX(s2.price) FROM shop s2 WHERE s1.article = s2.article)
Avec MySQL il vaut mieux le faire en deux étapes :
Cela peut se faire facilement avec une table temporaire:
CREATE TEMPORARY TABLE tmp ( article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL, price DOUBLE(16,2) DEFAULT '0.00' NOT NULL); LOCK TABLES article read; INSERT INTO tmp SELECT article, MAX(price) FROM shop GROUP BY article; SELECT article, dealer, price FROM shop, tmp WHERE shop.article=tmp.articel AND shop.price=tmp.price; UNLOCK TABLES; DROP TABLE tmp;
Si vous n'utislisez pas de table temporaire, il vous faut verrouiller la table.
"Est ce qu'il est impossible de faire cela avec une seule requête?"
Oui, mais en utilisant une astuce qui s'appelle : "MAX-CONCAT trick":
SELECT article, SUBSTRING( MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 7) AS dealer, 0.00+LEFT( MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 6) AS price FROM shop GROUP BY article; +---------+--------+-------+ | article | dealer | price | +---------+--------+-------+ | 0001 | B | 3.99 | | 0002 | A | 10.99 | | 0003 | C | 1.69 | | 0004 | D | 19.95 | +---------+--------+-------+
Le dernier exemple peut être fait de manière plus efficace, en effectuant la scission de la colonne au niveau du client; The last example can of course be made a bit more efficient by doing the
Il n'y a pas besoin de clé étrangère pour joindre deux tables.
La seule chose que MySQL
ne fait pas est de CHECK
(vérifier) que les clés que vous utilisez existent vraiment dans la table que vous réféencez, et qu'il n'efface par de lignes dnas une table avec une définition de clé étrangère. Si vous utilisez vos clés de manière habituelle, cela fonctionnera parfaitement.
CREATE TABLE persons ( id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, name CHAR(60) NOT NULL, PRIMARY KEY (id) ); CREATE TABLE shirts ( id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, style ENUM('t-shirt', 'polo', 'dress') NOT NULL, color ENUM('red', 'blue', 'orange', 'white', 'black') NOT NULL, owner SMALLINT UNSIGNED NOT NULL REFERENCES persons, PRIMARY KEY (id) ); INSERT INTO persons VALUES (NULL, 'Antonio Paz'); INSERT INTO shirts VALUES (NULL, 'polo', 'blue', LAST_INSERT_ID()), (NULL, 'dress', 'white', LAST_INSERT_ID()), (NULL, 't-shirt', 'blue', LAST_INSERT_ID()); INSERT INTO persons VALUES (NULL, 'Lilliana Angelovska'); INSERT INTO shirts VALUES (NULL, 'dress', 'orange', LAST_INSERT_ID()), (NULL, 'polo', 'red', LAST_INSERT_ID()), (NULL, 'dress', 'blue', LAST_INSERT_ID()), (NULL, 't-shirt', 'white', LAST_INSERT_ID()); SELECT * FROM persons; +----+---------------------+ | id | name | +----+---------------------+ | 1 | Antonio Paz | | 2 | Lilliana Angelovska | +----+---------------------+ SELECT * FROM shirts; +----+---------+--------+-------+ | id | style | color | owner | +----+---------+--------+-------+ | 1 | polo | blue | 1 | | 2 | dress | white | 1 | | 3 | t-shirt | blue | 1 | | 4 | dress | orange | 2 | | 5 | polo | red | 2 | | 6 | dress | blue | 2 | | 7 | t-shirt | white | 2 | +----+---------+--------+-------+ SELECT s.* FROM persons p, shirts s WHERE p.name LIKE 'Lilliana%' AND s.owner = p.id AND s.color <> 'white'; +----+-------+--------+-------+ | id | style | color | owner | +----+-------+--------+-------+ | 4 | dress | orange | 2 | | 5 | polo | red | 2 | | 6 | dress | blue | 2 | +----+-------+--------+-------+
Si l'administrateur vous a créé une base de données pour vous, alors vous pouvez directement commencer à l'utiliser. Sinon, il vous faut la créer vous même :
mysql> CREATE DATABASE menagerie;
Sous Unix, les noms de base de données sont sensibles à la casse (contrairement aux mots clés SQL), donc il faudra faire référence à votre base de données sous le nom menagerie
, et non pas Menagerie
, MENAGERIE
ou tout autre variante. Sous Windows, cette restriction ne s'applique pas, même si vous devez faire référence à vos bases et tables de la même manière tout au long d'une même commande).
Créer une base de données ne la selectionne pas automatiquement. Il faut le faire explicitement. Pour faire de menagerie
votre base courante, il faut utiliser la commande:
mysql> USE menagerie Database changed
La base n'a besoin d'être crée qu'une seule fois, mais il faudra la sélectionner à chaque fois que vous commencerez une session mysql
. Il suffira alors d'utiliser la même commande que ci-dessus. Alternativement, vous pouvez sélectionner une base dès la connexion, en passant le nom de la base après tous les paramètres de connexion : .
shell> mysql -h host -u user -p menagerie Enter password: ********
Remarquez bien que menagerie
n'est pas dans votre mot de passe. Si vous voulez transmettre votre mot de passe après l'option –p
, vous devez le faire sans espace entre le mot de passe et l'option : (e.g., tel que -pmypassword
, mais pas -p mypassword
). Cependant, mettre votre mot de passe dans la ligne de connexion n'est pas très recommandé, car cela vous rend vulnérable à tous les mouchards qui pourraient être sur votre machine.
Créer une base de données est facile, mais, jusqu'à présent, c'est vide. La commande SHOW TABLES
vous dira :
mysql> SHOW TABLES; Empty set (0.00 sec)
La partie la plus difficile est le choix de la structure de votre base de données, et des tables dont vous aurez besoin, et quelles colonnes seront nécessaires.
Vous pouvez envisager de créer une table qui créera un enregistrement pour chacun de vos animaux. Cette table portera le nom de animaux
et devrait contenir au minimum le nom de l'animal. Etant donné que le nom seul n'est pas vraiment intéressant, il faudra qu'il contienne aussi d'autres informations. Par exemple, si plusieurs personnes de votre famille ont des animaux domestiques, vous voudrez garder la liste de chaque maître. Vous voudrez peut être aussi conserver des informations basiques telles que le genre ou la race.
Et l'age ? Cela pourrait être intéressant à conserver, mais ce n'est pas une bonne chose à conserver dans une base de données. En effet, l'age change tous les jours, et il faudrait changer constamment la base de données. Au contraire, il est bien mieux de conserver la date de naissance. Alors, à chaque fois que vous aurez besoins de l'age, il suffira de faire la différence entre la date du jour et la date de naissance. MySQL disposent de puissantes fonctions de calculs sur les dates. Enregistrer la date de naissance plutôt quel l'age a d'autres atouts :
Vous pourrez utiliser la base de données pour garder en mémoire les dates d'anniversaires de vos animaux (Si cela vous semble un peu idiot, remarquez bien que c'est exactement la même chose que de conserver la date d'anniversaire de vos clients, et de leur envoyer cette carte d'anniversaire à la spontanéité toute informatique).
Vous pourrez faire des calculs d'age en relation avec d'autres dates. Par exemple, si vous enregistrer la date de mort, vous pourrez facilement calculer à quel age est mort votre compagnon.
Votre imagination fertile vous permettra sûrement d'imaginer une foule d'informations utiles pour garnir la table animaux
, mais les champs que nous venons d'identifier seront suffisant pour l'instant : le nom, le propriétaire, la race, le genre, la date de naissance et celle de mort.
Utilisez maintenant la fonction de création de table pour créer la votre :
mysql> CREATE TABLE animaux (nom VARCHAR(20), proprietaire VARCHAR(20), -> espece VARCHAR(20), genre CHAR(1), naissance DATE, mort DATE);
VARCHAR
est un bon choix pour le nom, le propriétaire et la race, car ces valeurs auront des longueurs variables. Les longueurs de ces colonnes n'ont pas besoin d'être toutes identiques, ni de valoir 20. Vous pouvez choisir n'importe quelle longueur entre 1 et 255, du moment que cela vous semble approprié (si vous vous trompez , vous pourrez toujours agrandir le champs avec la fonction MySQL : ALTER TABLE
).
Le genre des animaux peu prendre de nombreuses formes, comme par exemple "m"
et "f"
, ou peut être "male"
et "femelle"
. Le plus simple sera d'utiliser les caractères "m"
et "f"
.
L'utilisation du type DATE
pour représenter les dates de naissance naissance
et de mort mort
est un choix évident.
Maintenant que vous avez créer une table, , SHOW TABLES
devrait être plus loquace :
mysql> SHOW TABLES; +---------------------+ | Tables in menagerie | +---------------------+ | animaux | +---------------------+
Pour vérifier que la table a été créée comme vous le désiriez, utilisez la commande DESCRIBE
:
mysql> DESCRIBE animaux; +----------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------------+-------------+------+-----+---------+-------+ | nom | varchar(20) | YES | | NULL | | | proprietaire | varchar(20) | YES | | NULL | | | espece | varchar(20) | YES | | NULL | | | genre | char(1) | YES | | NULL | | | naissance | date | YES | | NULL | | | mort | date | YES | | NULL | | +----------------+-------------+------+-----+---------+-------+
Vous pouvez utiliser DESCRIBE
à tout moment, par exemple, si vous oubliez les noms de colonnes ou leur type.
Après avoir créé votre table, il faut la remplir. La fonction LOAD DATA
et INSERT
remplissent cette fonction.
Supposons que les informations sur vos animaux soient décrites comme dans le tableau ci-dessous : Remaquez bien que MySQL utilise un format de date de type AAAA-MM-JJ
; qui n'est pas le format standard.)
Etant donné que vous commencez avec une table vide, le meilleur moyen de remplir cette table est de créer un fichier texte, chaque ligne contenant les informations d'un animal, puis de le charger directement dans la table avec une seule commande.
Vous créez ainsi un fichier animaux.txt' contenant un enregistrement par ligne, avec des valeurs séparées par des tabulation, et dans le même ordre que l'ordre dans lequel les colonnes ont été listées dans la commande CREATE TABLE
. Pour les valeurs manquantes (comme par exemple, les genres inconnues, ou les dates de mort des animaux vivants), vous pouvez utiliser la valeur NULL
. Vous la représenterez dans le texte avec \N
. Par exemple, l'enregistrement de l'oiseau Whistler ressemblera à ceci :
Pour charger ce fichier `animaux.txt' dans la table animaux
, utilisez la commande suivante :
mysql> LOAD DATA LOCAL INFILE "animaux.txt" INTO TABLE animaux;
Vous pourriez spécifier le type de chaque colonne et le marqueur de fin de ligne dans la commande LOAD DATA
si vous le désiriez, mais les valeurs par défaut (tabulations et retour chariot) fonctionnent très bien ici.
Pour n'ajouter qu'un seul enregistrement à la fois, la fonction INSERT
est plus pratique : Dans sa forme la plus simple, vous fournissez les valeurs dans l'ordre des colonnes. Par exemple, si Diane recoit un hamster du nom de Puffball, vous pourriez ajouter un nouvel enregistrement avec la commande suivante :
mysql> INSERT INTO animaux -> VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);
Notez bien que les chaînes et les dates sont spécifiées avec des guillemets. De la même façon, vous pouvez insérer la valeur NULL
directement pour représenter une valeur manquante. N'utilisez pas \N
comme pour LOAD DATA
.
A partir de cet exemple, vous voyez que la commande INSERT
requiert nettement plus de frappe au clavier que la fonction LOAD DATA
La commande SELECT
sert à lire des informations d'une table.
La forme générale est la suivante :
SELECT what_to_select FROM which_table WHERE conditions_to_satisfy
what_to_select
indique ce que vous voulez affichier. Cela peut être une liste de champs, ou bien le joker *
qui signifie ``toutes les colonnes'' which_table
indique dans quelle table lire les informations. La clause WHERE
est optionnelle. Si elle est présente, conditions_to_satisfy
spécifie les conditions qu'une ligne doit remplir pour être retenue, et retournée.
La forme la plus simple de SELECT
permet d'obtenir la liste complète des ligne d'une table :
mysql> SELECT * FROM animaux; +----------+---------------+---------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +----------+---------------+---------+--------+----------------+------------+ | Fluffy | Harold | chat | f | 1993-02-04 | NULL | | Claws | Gwen | chat | m | 1994-03-17 | NULL | | Buffy | Harold | chien | f | 1989-05-13 | NULL | | Fang | Benny | chien | m | 1990-08-27 | NULL | | Bowser | Diane | chien | m | 1998-08-31 | 1995-07-29 | | Chirpy | Gwen | oiseau | f | 1998-09-11 | NULL | | Whistler | Gwen | oiseau | NULL | 1997-12-09 | NULL | | Slim | Benny | serpent | m | 1996-04-29 | NULL | | Puffball | Diane | hamster | f | 1999-03-30 | NULL | +----------+---------------+---------+--------+----------------+------------+
Cette forme de SELECT
est utile pour passer en revue une table, comme par exemple, une table que vous viendriez de charger. Dans cet exemple, la table ci-dessus montre qu'il y a eu une erreur dans le fichier. Bowser semble être né après être mort ! En consultant son dossier, vous vous apercevez que sa date correcte de naissance est 1989, et non pas 1998.
Il y a au moins deux façons de corriger cette erreur :
Editez le fichier `animaux.txt' pour corriger l'erreur, puis effacer la table ,et la recharger avec la DELETE
et LOAD DATA
:
mysql> DELETE FROM animaux; mysql> LOAD DATA LOCAL INFILE "animaux.txt" INTO TABLE animaux;
Cependant, en faisant cela, il vous faudra aussi insérer de nouveau la fiche de Puffball.
Ou bien, corriger seulement la fiche erronée avec une commande UPDATE
:
mysql> UPDATE animaux SET naissance = "1989-08-31" WHERE nom = "Bowser";
Dans cet exemple, on voit qu'il est facile de sélectionner toute la table. Mais généralement, ce n'est pas très pratique, surtout quand la table devient trop grande. En général, il s'agit de réponse à une question plus spécifique, pour laquelle il va falloir ajouter des contraintes sur les informations à retourner. Voyons maintenant quelques exemples de requêtes.
Il est bien sûr possible de ne sélectionner quelques lignes dans une table. Mettons que vous souhaitiez vérifier que la nouvelle date de naissance de Bowser's a bien été prise en compte. Il suffit de sélectionner l'enregistrement de Bowser comme ceci :
mysql> SELECT * FROM animaux WHERE nom = "Bowser"; +--------+--------------+---------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +--------+--------------+---------+--------+----------------+------------+ | Bowser | Diane | chien | m | 1989-08-31 | 1995-07-29 | +--------+--------------+---------+--------+----------------+------------+
Le résultat confirme bien que l'année de naissance est 1989, et non plus 1998.
Les comparaisons de chaîne sont généralement insensible à la casse : on aurait plus préciser le nom "bowser"
, "BOWSER"
, etc. Le résultat aurait été le même.
Vous pouvez faire des recherches sur d'autres colonnes que nom
. Par exemple, si vous voulez savoir quels animaux sont nés 1998, faites un test sur la colonne naissance
:
mysql> SELECT * FROM animaux WHERE naissance >= "1998-1-1"; +----------+--------------+---------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +----------+--------------+---------+--------+----------------+------------+ | Chirpy | Gwen | oiseau | f | 1998-09-11 | NULL | | Puffball | Diane | hamster | f | 1999-03-30 | NULL | +----------+--------------+---------+--------+----------------+------------+
Vous pouvez aussi combiner les conditions : par exemple, pour rechercher les chiennes
mysql> SELECT * FROM animaux WHERE espece = "chien" AND genre = "f"; +----------+--------------+---------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +----------+--------------+---------+--------+----------------+------------+ | Buffy | Harold | chien | f | 1989-05-13 | NULL | +----------+--------------+---------+--------+----------------+------------+
La requête précédente utilisait l'opérateur logique AND
(ET) Il y a aussi un opérateur OR
(OU) :
mysql> SELECT * FROM animaux WHERE espece = "serpent" OR espece = "oiseau"; +----------+--------------+---------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +----------+--------------+---------+--------+----------------+------------+ | Chirpy | Gwen | oiseau | f | 1998-09-11 | NULL | | Whistler | Gwen | oiseau | NULL | 1997-12-09 | NULL | | Slim | Benny | serpent | m | 1996-04-29 | NULL | +----------+--------------+---------+--------+----------------+------------+
AND
et OR
peut être utilisés dans la même requête. C'est alors une bonne idée d'utiliser des parenthèses pour préciser les regroupements :
mysql> SELECT * FROM animaux WHERE (espece = "chat" AND genre = "m") -> OR (espece = "chien" AND genre = "f"); +----------+--------------+---------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +----------+--------------+---------+--------+----------------+------------+ | Claws | Gwen | chat | m | 1994-03-17 | NULL | | Buffy | Harold | chien | f | 1989-05-13 | NULL | +----------+--------------+---------+--------+----------------+------------+
Il se peut que vous n'ayez pas besoin de toutes les colonnes de votre table, mais juste de quelques colonnes. Il suffit alors de citer les colonnes qui vous intéressent. Par exemple, si vous ne voulez voir que les noms des animaux, avec leur date de naissance, il suffit de ne sélectionner que les colonnes nom
et naissance
:
mysql> SELECT nom, naissance FROM animaux; +----------+------------+ | nom | naissance | +----------+------------+ | Fluffy | 1993-02-04 | | Claws | 1994-03-17 | | Buffy | 1989-05-13 | | Fang | 1990-08-27 | | Bowser | 1989-08-31 | | Chirpy | 1998-09-11 | | Whistler | 1997-12-09 | | Slim | 1996-04-29 | | Puffball | 1999-03-30 | +----------+------------+
Pour lister les propriétaires d'animaux, utilisez la requête suivante :
mysql> SELECT proprietaire FROM animaux; +---------------+ | proprietaire | +---------------+ | Harold | | Gwen | | Harold | | Benny | | Diane | | Gwen | | Gwen | | Benny | | Diane | +---------------+
Cependant, vous pouvez remarquer que cette requête simple affiche le champs proprietaire
de chaque ligne, ce qui conduit à avoir des redondances (comme Gwen). Pour ne les voir apparaître qu'une seule fois, il faut utiliser le mot clé DISTINCT
:
mysql> SELECT DISTINCT proprietaire FROM animaux; +---------------+ | proprietaire | +---------------+ | Benny | | Diane | | Gwen | | Harold | +---------------+
Vous pouvez encore combiner une clause WHERE
lors de la selection de lignes et de colonnes Par exemple, pour obtenir les dates de naissances des chiens et des chats, utilisez la requête suivante :
mysql> SELECT nom, espece, naissance FROM animaux -> WHERE espece = "chien" OR espece = "chat"; +--------+---------+------------+ | nom | espece | naissance | +--------+---------+------------+ | Fluffy | chat | 1993-02-04 | | Claws | chat | 1994-03-17 | | Buffy | chien | 1989-05-13 | | Fang | chien | 1990-08-27 | | Bowser | chien | 1989-08-31 | +--------+---------+------------+
Vous avez pu remarquer que les lignes précédentes ont été affichées dans un ordre aléatoire. Comme il est plus facile d'analyser une requête dont les lignes ont été triées, il vaut mieux trier ces lignes avec la clause : ORDER BY
:
Voici la liste des dates de naissances des animaux, classées par date :
mysql> SELECT nom, naissance FROM animaux ORDER BY naissance; +----------+------------+ | nom | naissance | +----------+------------+ | Buffy | 1989-05-13 | | Bowser | 1989-08-31 | | Fang | 1990-08-27 | | Fluffy | 1993-02-04 | | Claws | 1994-03-17 | | Slim | 1996-04-29 | | Whistler | 1997-12-09 | | Chirpy | 1998-09-11 | | Puffball | 1999-03-30 | +----------+------------+
Pour inverser l'ordre de tri, ajoutez le mot clé DESC
(descendant) après le nom de la colonne que vous classez.
mysql> SELECT nom, naissance FROM animaux ORDER BY naissance DESC; +----------+------------+ | nom | naissance | +----------+------------+ | Puffball | 1999-03-30 | | Chirpy | 1998-09-11 | | Whistler | 1997-12-09 | | Slim | 1996-04-29 | | Claws | 1994-03-17 | | Fluffy | 1993-02-04 | | Fang | 1990-08-27 | | Bowser | 1989-08-31 | | Buffy | 1989-05-13 | +----------+------------+
Vous pouvez faire des classements avec plusieurs critères de tri. Par exemple, pour trier les animaux pas espèce, puis par naissance pour chaque type d'animaux, utilisez la requête suivante :
mysql> SELECT nom, espece, naissance FROM animaux ORDER BY espece, naissance DESC; +----------+---------+------------+ | nom | espece | naissance | +----------+---------+------------+ | Chirpy | oiseau | 1998-09-11 | | Whistler | oiseau | 1997-12-09 | | Claws | chat | 1994-03-17 | | Fluffy | chat | 1993-02-04 | | Fang | chien | 1990-08-27 | | Bowser | chien | 1989-08-31 | | Buffy | chien | 1989-05-13 | | Puffball | hamster | 1999-03-30 | | Slim | serpent | 1996-04-29 | +----------+---------+------------+
Notez bien que le mot clé DESC
ne s'applique qu'à la colonne le précédent immédiatement (naissance
); espece
étant trié dans l'ordre ascendant.
MySQL possède de puissantes fonctions pour effectuer des calculs sur les dates, comme par exemple, calculer un age, ou extraire des parties de date.
Pour déterminer l'age de chacun des animaux, il faut calculer la différence entre la naissance et la date courante. Puis, convertir ces deux dates en jours, et diviser le tout par 365, pour avoir le nombre d'année.
mysql> SELECT nom, (TO_DAYS(NOW())-TO_DAYS(naissance))/365 FROM animaux; +----------+-----------------------------------------+ | nom | (TO_DAYS(NOW())-TO_DAYS(naissance))/365 | +----------+-----------------------------------------+ | Fluffy | 6.15 | | Claws | 5.04 | | Buffy | 9.88 | | Fang | 8.59 | | Bowser | 9.58 | | Chirpy | 0.55 | | Whistler | 1.30 | | Slim | 2.92 | | Puffball | 0.00 | +----------+-----------------------------------------+
Bien que cette requête fasse bien ce qu'on lui demande, il y a de la place pour quelques améliorations. En premier lieu, les résultats gagneraient à être classés. De plus, le titre de la colonne n'est pas très explicite.
Le premier problème peut être résolu avec une clause ORDER BY nom
qui va classer par ordre alphabétique. Pour régler le problème du titre, nous allons utiliser un alias.
mysql> SELECT nom, (TO_DAYS(NOW())-TO_DAYS(naissance))/365 AS age -> FROM animaux ORDER BY nom; +----------+------+ | nom | age | +----------+------+ | Bowser | 9.58 | | Buffy | 9.88 | | Chirpy | 0.55 | | Claws | 5.04 | | Fang | 8.59 | | Fluffy | 6.15 | | Puffball | 0.00 | | Slim | 2.92 | | Whistler | 1.30 | +----------+------+
Pour trier les résultats par age
plutôt que par nom nom
, il suffit de le mettre dans la clause ORDER BY
:
mysql> SELECT nom, (TO_DAYS(NOW())-TO_DAYS(naissance))/365 AS age -> FROM animaux ORDER BY age; +----------+------+ | nom | age | +----------+------+ | Puffball | 0.00 | | Chirpy | 0.55 | | Whistler | 1.30 | | Slim | 2.92 | | Claws | 5.04 | | Fluffy | 6.15 | | Fang | 8.59 | | Bowser | 9.58 | | Buffy | 9.88 | +----------+------+
Une requête similaire pourrait calculer l'age de mort des animaux morts. Pour cela, vous allez déterminer les animaux morts, en testant la colonne mort
à NULL
. Puis, pour les valeurs non-NULL
, calculez l'age avec les colonnes mort
et naissance
:
mysql> SELECT nom, naissance, mort, (TO_DAYS(mort)-TO_DAYS(naissance))/365 AS age -> FROM animaux WHERE mort IS NOT NULL ORDER BY age; +--------+------------+------------+------+ | nom | naissance | mort | age | +--------+------------+------------+------+ | Bowser | 1989-08-31 | 1995-07-29 | 5.91 | +--------+------------+------------+------+
La requête utilise mort IS NOT NULL
plutôt que mort != NULL
car NULL
est une valeur spéciale. Cela est expliqué plus loin. Allez 8.4.3.6 Travailler avec la valeur NULL
.
Et comment rechercher les animaux dont l'anniversaire sera le mois prochain ? Pour ce genre de calculs, year et day sont inutiles, il suffit d'extraire le mois de la colonne naissance
. MySQL fournit plusieurs fonctions d'extraction comme par exemple YEAR()
, MONTH()
et DAY()
. MONTH()
est le plus approprié ici. Pour voir comment cela fonction, exécutez la commande suivante, qui naissance
et MONTH(naissance)
:
mysql> SELECT nom, naissance, MONTH(naissance) FROM animaux; +----------+------------+------------------+ | nom | naissance | MONTH(naissance) | +----------+------------+------------------+ | Fluffy | 1993-02-04 | 2 | | Claws | 1994-03-17 | 3 | | Buffy | 1989-05-13 | 5 | | Fang | 1990-08-27 | 8 | | Bowser | 1989-08-31 | 8 | | Chirpy | 1998-09-11 | 9 | | Whistler | 1997-12-09 | 12 | | Slim | 1996-04-29 | 4 | | Puffball | 1999-03-30 | 3 | +----------+------------+------------------+
Trouver les animaux dont la date de naissance est le mois prochain est facile. En supposant que nous soyons au mois d'avril. Alors, le mois est le 4, et il suffit de rechercher les animaux nés au mois de May (5), comme ceci :
mysql> SELECT nom, naissance FROM animaux WHERE MONTH(naissance) = 5; +-------+----------------+ | nom | naissance | +-------+----------------+ | Buffy | 1989-05-13 | +-------+----------------+
Il y a bien sur un cas particulier: décembre. Il ne suffit pas seulement d'ajouter 1 à numéro du mois courant et de chercher les dates d'anniversaires correspondantes, car personne ne nait au mois 13. A la place, il faut chercher les animaux qui sont nés au mois de janvier.
Vous pourriez écrire une requête qui fonctionne, quelque soit le mois courant. De cette façon, vous n'aurez pas à utiliser un numéro particulier de mois dans la requête. DATE_ADD()
vous permettra d'ajouter une durée de temps à une date. Si vous ajoutez un mois à la date de NOW()
, puis vous en sortez le mois avec MONTH()
, le résultat sera bien le mois suivant.
mysql> SELECT nom, naissance FROM animaux -> WHERE MONTH(naissance) = MONTH(DATE_ADD(NOW(), INTERVAL 1 MONTH));
Une autre manière de faire serait d'ajouter 1
au mois courant, puis d'utiliser la (MOD
) pour ``boucler'' à la fin de l'année, et faire correspondre janvier et décembre :
mysql> SELECT nom, naissance FROM animaux -> WHERE MONTH(naissance) = MOD(MONTH(NOW()),12) + 1;
NULL
La valeur NULL
peut se comporter de manière surprenante si vous l'utilisez. Conceptuellement, NULL
signifie ``valeur manquante '' ou `` valeur inconnue'' et il est traité de manière légèrement différente des autres valeurs. Pour tester une valeur à NULL
, vous ne pouvez pas utiliser les opérateurs de comparaison habituels, tels que =
, <
or !=
. Pour vous en convaincre, essayez la requête suivante :
mysql> SELECT 1 = NULL, 1 != NULL, 1 < NULL, 1 > NULL; +----------+-----------+----------+----------+ | 1 = NULL | 1 != NULL | 1 < NULL | 1 > NULL | +----------+-----------+----------+----------+ | NULL | NULL | NULL | NULL | +----------+-----------+----------+----------+
Clairement, vous n'obtiendrez aucun résultat significatif de ces comparaisons. Utilisez les opérateurs IS NULL
et IS NOT NULL
:
mysql> SELECT 1 IS NULL, 1 IS NOT NULL; +-----------+---------------+ | 1 IS NULL | 1 IS NOT NULL | +-----------+---------------+ | 0 | 1 | +-----------+---------------+
Avec MySQL, 0 signifie faux et 1 signifie vrai.
Cette gestion spéciale de NULL
explique pourquoi, dans la section précédente, il était nécessaire de savoir quels animaux étaient encore vivant, en utilisant mort IS NOT NULL
à la place de mort != NULL
.
MySQL propose les méthodes de recherche standard du SQL, mais aussi les recherches à base d'expression régulière, similaire à celle utilisées dans les utilitaires Unix, tels que vi
, grep
et sed
.
Les méthodes de recherche SQL vous permettent d'utiliser le caractère ``_'' pour remplacer n'importe quel caractère unique, et ``%'' pour remplacer n'importe quel nombre de caractères (y compris le caractère 0). Les recherches SQL sont insensibles à la casse. Reportez vous aux exemples ci-dessous. Remarquez bien que l'on n'utilise pas =
ou !=
mais plutôt LIKE
ou NOT LIKE
.
Recherche des noms commençant par ``b'':
mysql> SELECT * FROM animaux WHERE nom LIKE "b%"; +--------+---------------+--------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +--------+---------------+--------+--------+----------------+------------+ | Buffy | Harold | chien | f | 1989-05-13 | NULL | | Bowser | Diane | chien | m | 1989-08-31 | 1995-07-29 | +--------+---------------+--------+--------+----------------+------------+
Recherche des noms finissant par :``fy'':
mysql> SELECT * FROM animaux WHERE nom LIKE "%fy"; +--------+---------------+--------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +--------+---------------+--------+--------+----------------+------------+ | Fluffy | Harold | chat | f | 1993-02-04 | NULL | | Buffy | Harold | chien | f | 1989-05-13 | NULL | +--------+---------------+--------+--------+----------------+------------+
Recherche des noms contenant ``w'':
mysql> SELECT * FROM animaux WHERE nom LIKE "%w%"; +----------+---------------+--------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +----------+---------------+--------+--------+----------------+------------+ | Claws | Gwen | chat | m | 1994-03-17 | NULL | | Bowser | Diane | chien | m | 1989-08-31 | 1995-07-29 | | Whistler | Gwen | oiseau | NULL | 1997-12-09 | NULL | +----------+---------------+--------+--------+----------------+------------+
Recherche des noms contenant exactement 5 caractères, utilisez le caractère ``_'' :
mysql> SELECT * FROM animaux WHERE nom LIKE "_____"; +----------+---------------+--------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +----------+---------------+--------+--------+----------------+------------+ | Claws | Gwen | chat | m | 1994-03-17 | NULL | | Buffy | Harold | chien | f | 1989-05-13 | NULL | +----------+---------------+--------+--------+----------------+------------+
L'autre type de recherche disponible avec MySQL est les expression régulières. Pour utiliser ce type de recherche, il faut ajouter les mots clé REGEXP
et NOT REGEXP
(ou RLIKE
t NOT RLIKE
, qui sont des synonymes).
Les caractéristiques des expressions régulières sont :
Pour illustrer le fonctionnement des expressions régulières, les requêtes précédentes ont été réécrites en utilisant les expressions régulières.
Recherche des noms commençant par ``b'': on utilise ``^'' pour indiquer le début de la valeur, et ``[bB]'' pour rechercher indifféremment, ``b'' minuscule ou majuscule.
mysql> SELECT * FROM animaux WHERE nom REGEXP "^[bB]"; +--------+---------------+--------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +--------+---------------+--------+--------+----------------+------------+ | Buffy | Harold | chien | f | 1989-05-13 | NULL | | Bowser | Diane | chien | m | 1989-08-31 | 1995-07-29 | +--------+---------------+--------+--------+----------------+------------+
Recherche des noms finissant par :``fy'': on utilise ``$'' pour indiquer la fin de la valeur
+--------+---------------+--------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +--------+---------------+--------+--------+----------------+------------+ | Fluffy | Harold | chat | f | 1993-02-04 | NULL | | Buffy | Harold | chien | f | 1989-05-13 | NULL | +--------+---------------+--------+--------+----------------+------------+
Recherche des noms contenant ``w'':, on utilise ``[wW]'' pour rechercher les ``w', 'minuscule ou majuscule :
mysql> SELECT * FROM animaux WHERE nom REGEXP "[wW]"; +----------+---------------+--------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +----------+---------------+--------+--------+----------------+------------+ | Claws | Gwen | chat | m | 1994-03-17 | NULL | | Bowser | Diane | chien | m | 1989-08-31 | 1995-07-29 | | Whistler | Gwen | oiseau | NULL | 1997-12-09 | NULL | +----------+---------------+--------+--------+----------------+------------+
Etant donné qu'une expression régulière est vrai si elle est vrai sur une partie d'une valeur, il n'est pas besoin de caractères spéciaux.
Recherche des noms contenant exactement 5 caractères, utilisez ``^'' et ``$'' pour indiquer le début et la fin de la chaîne, et 5 fois ``.'' pour les 5 caractères.
mysql> SELECT * FROM animaux WHERE nom REGEXP "^.....$"; +----------+---------------+--------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +----------+---------------+--------+--------+----------------+------------+ | Claws | Gwen | chat | m | 1994-03-17 | NULL | | Buffy | Harold | chien | f | 1989-05-13 | NULL | +----------+---------------+--------+--------+----------------+------------+
Vous auriez pu aussi utiliser l'opérateur ``{n''} `` n
-fois'':
mysql> SELECT * FROM animaux WHERE nom REGEXP "^.{5}$"; +----------+---------------+--------+--------+----------------+------------+ | nom | proprietaire | espece | genre | naissance | mort | +----------+---------------+--------+--------+----------------+------------+ | Claws | Gwen | chat | m | 1994-03-17 | NULL | | Buffy | Harold | chien | f | 1989-05-13 | NULL | +----------+---------------+--------+--------+----------------+------------+
Les bases de données sont souvent utilisées pour répondre aux questions du type : ``combien de fois une information est-elle enregistrée dans une table?''. Par exemple, vous pouvez souhaiter connaître le nombre d'animaux que vous avez, ou le nombre d'animaux de chaque propriétaire, ou encore toutes sortes de statistiques sur les animaux.
Pour compter le nombre total d'animaux que vous avez, il suffit de compter le nombre de ligne dans la table animaux
, puisqu'il y a un enregistrement par animal. La fonction COUNT()
compte le nombre de ligne non-NULL
. Votre requête ressemblera alors à :
mysql> SELECT COUNT(*) FROM animaux; +----------+ | COUNT(*) | +----------+ | 9 | +----------+
Précédemment, vous avez recherché les noms des propriétaires d'animaux. Vous pouvez utiliser la fonction COUNT()
pour connaître le nombre d'animaux que chaque propriétaire a :
mysql> SELECT proprietaire, COUNT(*) FROM animaux GROUP BY proprietaire; +---------------+----------+ | proprietaire | COUNT(*) | +---------------+----------+ | Benny | 2 | | Diane | 2 | | Gwen | 3 | | Harold | 2 | +---------------+----------+
Remarques: l'utilisation de la clause GROUP BY
qui rassemble les lignes par proprietaire
. Sans cette clause, vous obtenez le message d'erreur suivant :
mysql> SELECT proprietaire, COUNT(proprietaire) FROM animaux; ERROR 1140 at line 1: Mixing of GROUP columns (MIN(),MAX(),COUNT()...) with no GROUP columns is illegal if there is no GROUP BY clause
COUNT()
et GROUP BY
sont utiles pour caractériser vos informations dans de nombreuses situations : Les exemples suivant effectuent des statistiques sur vos animaux :
Nombre d'animaux par espèce
mysql> SELECT espece, COUNT(*) FROM animaux GROUP BY espece; +----------+----------+ | espece | COUNT(*) | +----------+----------+ | oiseau | 2 | | chat | 2 | | chien | 3 | | hamster | 1 | | serpent | 1 | +----------+----------+
Nombre d'animaux par genre:
mysql> SELECT genre, COUNT(*) FROM animaux GROUP BY genre; +-------+----------+ | genre | COUNT(*) | +-------+----------+ | NULL | 1 | | f | 4 | | m | 4 | +-------+----------+
(Dans cette réponse, NULL
indique ``genre inconnu.'')
Nombre d'animaux par espece et genre:
mysql> SELECT espece, genre, COUNT(*) FROM animaux GROUP BY espece, genre; +---------+-------+----------+ | espece | genre | COUNT(*) | +---------+-------+----------+ | oiseau | NULL | 1 | | oiseau | f | 1 | | chat | f | 1 | | chat | m | 1 | | chien | f | 1 | | chien | m | 2 | | hamster | f | 1 | | serpent | m | 1 | +---------+-------+----------+
Il n'y a pas besoin d'utiliser la table entière avec la fonction COUNT()
. Par exemple, la requête précédente effectuée sur la population de chien et de chat devient:
mysql> SELECT espece, genre, COUNT(*) FROM animaux -> WHERE espece = "chien" OR espece = "chat" -> GROUP BY espece, genre; +---------+-------+----------+ | espece | genre | COUNT(*) | +---------+-------+----------+ | chat | f | 1 | | chat | m | 1 | | chien | f | 1 | | chien | m | 2 | +---------+-------+----------+
Ou, pour avoir le nombre d'animaux par genre, et pour les espèces connues :
mysql> SELECT espece, genre, COUNT(*) FROM animaux -> WHERE genre IS NOT NULL -> GROUP BY espece, genre; +---------+-------+----------+ | espece | genre | COUNT(*) | +---------+-------+----------+ | oiseau | f | 1 | | chat | f | 1 | | chat | m | 1 | | chien | f | 1 | | chien | m | 2 | | hamster | f | 1 | | serpent | m | 1 | +---------+-------+----------+
La table animaux
contient la liste des animaux que vous avez. Vous pourriez vouloir enregistrer d'autres informations à leur sujet, telles que des évènements de leur vie, comme les visites chez le vétérinaire, ou les dates des portées de petits : vous avez besoin d'une autre table. A quoi va t elle ressembler ?
Avec ces indications, la requête de CREATE TABLE
va ressembler à ceci :
mysql> CREATE TABLE event (nom VARCHAR(20), date DATE, -> type VARCHAR(15), remark VARCHAR(255));
Comme pour la table animaux
table, il est plus facile de charger les premières valeurs à partir d'un fichier, dont les champs sont délimités avec des tabulations :
Chargez les informations comme ceci :
mysql> LOAD DATA LOCAL INFILE "event.txt" INTO TABLE event;
Etant donné ce que vous avez appris avec les requêtes sur la table animaux
table, vous devriez être capable d'exécuter des requêtes sur la table event
; les principes sont les mêmes. Mais la table event
pourrait se révéler insuffisante pour répondre à vos questions.
Supposons que vous voulez avoir l'age des animaux lorsqu'ils ont eu leur portée. La table event
indique quand ils ont eu leur portée, mais pour calculer l'age de la mère, il faut aussi sa date de naissance. Etant donné que cette date est stockée dans la table animaux
, vous avez besoin des deux tables dans la même requête :
mysql> SELECT animaux.nom, (TO_DAYS(date) - TO_DAYS(naissance))/365 AS age, remarque -> FROM animaux, event -> WHERE animaux.nom = event.nom AND type = "portée"; +--------+------+-------------------------------+ | nom | age | remarque | +--------+------+-------------------------------+ | Fluffy | 2.27 | 4 chatons, 3 femelles, 1 male | | Buffy | 4.12 | 5 chiots, 2 femelles, 3 male | | Buffy | 5.10 | 3 chiots, 3 femelles | +--------+------+-------------------------------+
Il faut remarquer plusieurs choses à propos de cette requête :
FROM
est une liste contenant les noms des deux tables, car la requête clause va chercher des informations dans ces deux tables.
nom
. La requête utilise une clause WHERE
pour rechercher et assortir les valeurs des deux tables, avec la colonne nom
.
nom
il faut préciser la table d'appartenance de ces colonnes à chaque référence. C'est facilement faisable en ajoutant simplement le nom de la table devant le nom de la colonne.
Les regroupements sont aussi possibles sur une même table. Cela revient à comparer des valeurs d'une table avec d'autres valeurs de la même table. Par exemple, pour marier vos animaux entre eux, vous pouvez faire un regroupement de la table animaux
avec elle-même pour rechercher les males et femelles de la même espèce :
mysql> SELECT p1.nom, p1.genre, p2.nom, p2.genre, p1.espece -> FROM animaux AS p1, animaux AS p2 -> WHERE p1.espece = p2.espece AND p1.genre = "f" AND p2.genre = "m"; +--------+-------+--------+-------+---------+ | nom | genre | nom | genre | espece | +--------+-------+--------+-------+---------+ | Fluffy | f | Claws | m | chat | | Buffy | f | Fang | m | chien | | Buffy | f | Bowser | m | chien | +--------+-------+--------+-------+---------+
Dans cette requête, plusieurs alias sont définis pour pouvoir faire référence à chaque instance de la table, et à la bonne colonne.
Que se passe t il si vous oubliez le nom d'une base de données, d'une table ou la structure d'une table donnée ? MySQL résoud ce problème avec plusieurs commandes qui fournissent des informations sur les bases et les tables.
Vous avez déjà rencontré SHOW DATABASES
, qui liste les bases gérés par le serveur. Pour connaître la base de données courante, utilisez DATABASE()
:
mysql> SELECT DATABASE(); +------------+ | DATABASE() | +------------+ | menagerie | +------------+
Si vous n'avez pas de base sélectionnée, le résultat est vide.
Pour connaître les tables de la base de données courante, (par exemple, si vous n'êtes pas sur du nom d'une table), utilisez la commande suivante :
mysql> SHOW TABLES; +---------------------+ | Tables in menagerie | +---------------------+ | event | | animaux | +---------------------+
Pour connaître les colonnes d'une table, (par exemple, si vous n'êtes pas sur du nom d'une colonne), utilisez la commande suivante :
mysql> DESCRIBE animaux; +----------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------------+-------------+------+-----+---------+-------+ | nom | varchar(20) | YES | | NULL | | | proprietaire | varchar(20) | YES | | NULL | | | espece | varchar(20) | YES | | NULL | | | genre | char(1) | YES | | NULL | | | naissance | date | YES | | NULL | | | mort | date | YES | | NULL | | +----------------+-------------+------+-----+---------+-------+
Field
donne le nom de la colonne, Type
est le type de données, Null
indique si la colonne accepte la valeur NULL
ou pas, Key
indique que la colonne est manual_tocée, et Default
indique la valeur par défaut de la colonne.
Si vous avez des manual_toc sur une table, SHOW manual_toc FROM tbl_nom
fournit la liste des informations les concernant.
mysql
en mode batch
Dans les sections précédentes, vous avez utilisé mysql
de manière interactive pour entrer des requête et voir les résultats.Vous pouvez aussi utiliser mysql
en mode batch. Pour cela, il faut mettre les commandes que vous souhaitez exécuter dans un fichier, puis indiquez à mysql
qu'il faut l'utiliser comme fichier d'entrée.
shell> mysql < batch-file
Si vous devez préciser des paramètres de connexions sur la ligne de commande, elle peut ressembler à ceci :
shell> mysql -h host -u user -p < batch-file Enter password: ********
Quand vous utilisez mysql
de cette façon, vous créez un fichier de script, puis exécutez ce script.
Pourquoi utiliser un script ? Voici quelques réponses :
shell> mysql < batch-file | more
shell> mysql < batch-file > mysql.out
Le format de réponse en mode batch est plus concis qu'en mode intéractif. Par exemple SELECT DISTINCT espece FROM animaux
ressemble à ceci ,en mode intéractif :
+---------+ | espece | +---------+ | oiseau | | chat | | chien | | hamster | | serpent | +---------+
Mais en mode batch, il ressemble à ceci :
espece oiseau chat chien hamster serpent
Pour obtenir un format de réponse " intéractif " à partir du mode batch, utilisez l'option mysql -t
. Pour avoir aussi les commandes exécutées utilisez l'option mysql -vvv
.
Chez Analytikerna and Lentus (NDT : société de l'auteur), nous avons pris en charge l'étude du système et l'architecture des données pour un grand projet de recherche. Ce projet est une collaboration entre l' Institut de médecine environnementale à Karolinska Institutet, Stockholm et la Section Recherche Clinique sur l'age et la psychologie, de l'université de Californie du Sud.
Ce projet avait une grosse partie d'enquête, où tous les jumeaux suédois de plus de 65 ans étaient interviewés par téléphone. Les jumeaux qui remplissaient certains critères étaient admis dans la phase suivante de l'enquête. Dans cette deuxième phase, les jumeaux qui souhaitaient participer, recevaient la visite d'un docteur et d'une infirmière. Une partie des questionnaires étaient des examens physiques et neuropsychologiques, des tests de laboratoire, des scanners du cerveau, des analyses psychologique, et des études généalogiques. De plus, des informations étaient rassemblées sur les risques médicaux et environnementaux.
Pour plus d'information a propos de ce projet, suivez le lien suivant (en anglais) :
http://www.imm.ki.se/TWIN/TWINUKW.HTM
La deuxième partie du projet est accessible par une interface web, écrite en Perl et MySQL.
Chaque nuit, les informations des réunions étaient inséréees dans les base MySQL.
8.7.1 Trouver tous les jumeaux non distribués
Les requêtes suivantes sont utilisées pour sélectionner les couples de jumeaux qui accèderont à la deuxième phase :
select concat(p1.id, p1.tvab) + 0 as tvid, concat(p1.christian_nom, " ", p1.surnom) as Nom, p1.postal_code as Code, p1.city as City, pg.abrev as Area, if(td.participation = "Aborted", "A", " ") as A, p1.dead as dead1, l.event as event1, td.suspect as tsuspect1, id.suspect as isuspect1, td.severe as tsevere1, id.severe as isevere1, p2.dead as dead2, l2.event as event2, h2.nurse as nurse2, h2.doctor as doctor2, td2.suspect as tsuspect2, id2.suspect as isuspect2, td2.severe as tsevere2, id2.severe as isevere2, l.finish_date from twin_project as tp /* For Twin 1 */ left join twin_data as td on tp.id = td.id and tp.tvab = td.tvab left join informant_data as id on tp.id = id.id and tp.tvab = id.tvab left join harmony as h on tp.id = h.id and tp.tvab = h.tvab left join lentus as l on tp.id = l.id and tp.tvab = l.tvab /* For Twin 2 */ left join twin_data as td2 on p2.id = td2.id and p2.tvab = td2.tvab left join informant_data as id2 on p2.id = id2.id and p2.tvab = id2.tvab left join harmony as h2 on p2.id = h2.id and p2.tvab = h2.tvab left join lentus as l2 on p2.id = l2.id and p2.tvab = l2.tvab, person_data as p1, person_data as p2, postal_groups as pg where /* p1 gets main twin and p2 gets his/her twin. */ /* ptvab is a field inverted from tvab */ p1.id = tp.id and p1.tvab = tp.tvab and p2.id = p1.id and p2.ptvab = p1.tvab and /* Just the sceening survey */ tp.survey_no = 5 and /* Skip if partner died before 65 but allow emigration (dead=9) */ (p2.dead = 0 or p2.dead = 9 or (p2.dead = 1 and (p2.mort_date = 0 or (((to_days(p2.mort_date) - to_days(p2.naissanceday)) / 365) >= 65)))) and ( /* Twin is suspect */ (td.future_contact = 'Yes' and td.suspect = 2) or /* Twin is suspect - Informant is Blessed */ (td.future_contact = 'Yes' and td.suspect = 1 and id.suspect = 1) or /* No twin - Informant is Blessed */ (ISNULL(td.suspect) and id.suspect = 1 and id.future_contact = 'Yes') or /* Twin broken off - Informant is Blessed */ (td.participation = 'Aborted' and id.suspect = 1 and id.future_contact = 'Yes') or /* Twin broken off - No inform - Have partner */ (td.participation = 'Aborted' and ISNULL(id.suspect) and p2.dead = 0)) and l.event = 'Finished' /* Get at area code */ and substring(p1.postal_code, 1, 2) = pg.code /* Not already distributed */ and (h.nurse is NULL or h.nurse=00 or h.doctor=00) /* Has not refused or been aborted */ and not (h.status = 'Refused' or h.status = 'Aborted' or h.status = 'Died' or h.status = 'Other') order by tvid;
Quelques explications s'imposent :
concat(p1.id, p1.tvab) + 0 as tvid
On veut trier les valeurs avec la concaténation de id
et tvab
dans un ordre numérique. Ajouter 0
au nombre force MySQL à traiter le résultat comme un nombre
column id
Ceci identifiera un couple de jumeaux. C'est une clé commune à toutes les tables.
column tvab
Cette colonne identifie un des jumeaux dans un couple. Il prend la valeur de 1
ou 2
.
column ptvab
C'est le complémentaire de la colonne précédente. Quand tvab
vaut 1
celle-ci vaut 2
, et vice versa. Elle sert à éviter des saisie, et permet à MySQL d'optimiser la requête.
Cette requête démontre, entre autres choses, comment faire des recherches dans une table à partir de la même table, grÅce à un regroupement ( (p1
et p2
). Dans l'exemple ci-dessus, on s'en sert pour vérifier si le deuxième jumeau n'est pas mort avant l'age de 65 ans. Dans ce cas, la ligne n'est pas renvoyée.
Toutes les informations ci-dessus existent dans les tables sur les jumeaux. Il y a toujours une clé sur id,tvab
(toutes tables) et id,ptvab
(person_data
) pour rendre les requêtes plus rapides.
Sur notre serveur de production (une station Sun UltraSPARC 200MHz), cettre requête retourne entre 150 et 200 lignes, et prend moins d'une seconde.
Le nombre courant de ligne dans les tables sont les suivants :
Chaque interview est conclu par un status appelé event
. La requête ci-dessous est utilisée pour créer une table avec toutes les paires de jumeaux. Elle indique aussi le nombre de couples qui ont terminé les entretiens, les couples où un seul jumeau a été interrogé, les couples qui ont refusé, etc…
select t1.event, t2.event, count(*) from lentus as t1, lentus as t2, twin_project as tp where /* We are looking at one pair at a time */ t1.id = tp.id and t1.tvab=tp.tvab and t1.id = t2.id /* Just the sceening survey */ and tp.survey_no = 5 /* This makes each pair only appear once */ and t1.tvab='1' and t2.tvab='2' group by t1.event, t2.event;
mysqld
peut émettre des messages d'erreur dans les langues suivantes :
Hollandais, Anglais (par défaut), Estonien, Français, Allemand, Hongrois, Italien,
Norvégien, Polonais, Portugais, Espagnol et Suédois.
Pour démarrer mysqld
avec une langue donnée, utilisez l'option --language=lang
ou -L lang
. Par exemple :
shell> mysqld --language=swedish
ou:
shell> mysqld --language=/usr/local/share/swedish
Notez que tous les noms de langues sont spécifiés en minuscules.
Le fichie de langue est situé (par défaut, dans le dossier `mysql_base_dir/share/LANGUAGE/'.
Pour modifier le fichier de message d'erreur, il vous faut éditer le fichier `errmsg.txt' et exécuter la commande suivante pour générer le fichier `errmsg.sys' :
shell> comp_err errmsg.txt errmsg.sys
Si vous mettez à jour MySQL, n'oubliez pas de répeter la même manoeuvre avec le nouveau fichier @new `errmsg.txt'.
Par défaut, MySQL utilise le jeu de caractère ISO-8859-1 (Latin1). C'est le jeu de caractères utilisé aux USA et en Europe Occidentale.
Le jeu de caractères détermine les caractères autorisés dans les noms, et la méthode de tri utilisée dans les clauses ORDER BY
et GROUP BY
de la commandes SELECT
.
Vous pouvez changer le jeu de caractères au moment de la compilation, en utilisant l'option --with-charset=charset
de configure
.
4.7.1 Introduction à l'installation rapide.
Pour ajouter un nouveau jeu de caractères à MySQL, utilisez la procédure suivante :
MYSET
.
ctype_MYSET
, to_lower_MYSET
etc...
to_lower[]
et to_upper[]
sont de simples tableaux qui contiennent les caractères minuscules et majuscules du jeu de caractère. Par exemple :
to_lower['A'] doit contenir 'a' to_upper['a'] doit contenir 'A'
sort_order[]
est une map qui indique comment les caractères doivent être ordonné
lors des comparaisons et des tris.
Pour la plus part des jeux de caractères, c'est la même valeur que pour to_upper[]
(ce qui signifie que le tri sera insensible à la casse). MySQL effectuera les tris en se basant sur la valeur de sort_order[character]
.
ctype[]
est un tableau de valeurs de bit, avec un élément par caractère.
(Notez que to_lower[]
, to_upper[]
et sort_order[]
sont indexés par valeur de caractère, mais que ctype[]
est indexé par valeur de caractère +1. C'est une vieille technique qui permet de gérer les EOF).
Vous pouvez trouver la définitions de ces champs de bit dans `m_ctype.h':
#define _U 01 /* Majuscule */ #define _L 02 /* Minuscule */ #define _N 04 /* Chiffre */ #define _S 010 /* Espacement*/ #define _P 020 /* Ponctuation */ #define _C 040 /* Caractère de contrôle */ #define _B 0100 /* Blanc */ #define _X 0200 /* Chiffre hexadécimal */L'entrée de
ctype[]
pour chaque caractère doit être l'union des masques de bits qui décrivent le caractère.
Par exemple, 'A'
est une caractère majuscule, (_U
) mais aussi un
chiffre hexadécimal. (_X
), donc son type devrait contenir ctype['A'+1]
_U + _X = 01 + 0200 = 0201
CHARSETS_AVAILABLE
de configure.in
.
Si vous créez un jeu de caractères multi byte, vous pouvez utiliser la macro _MB
. Dans le fichier `include/m_ctype.h.in', ajouter :
#define MY_CHARSET_MYSET X #if MY_CHARSET_CURRENT == MY_CHARSET_MYSET #define USE_MB #define USE_MB_IDENT #define ismbchar(p, end) (...) #define ismbhead(c) (...) #define mbcharlen(c) (...) #define MBMAXLEN N #endif
où :
MY_CHARSET_MYSET | Une valeur de jeu de caractère unique. |
USE_MB | Ce jeu de caractère a des caractères multi-byte, géré par ismbhead() et mbcharlen()
|
USE_MB_IDENT | (optionnel) Si défini, vous pouvez utiliser des noms de tables et de colonnes avec des caractères multi bytes. |
ismbchar(p, e) | retourne 0 si p ne contient pas de caractère multi-byte , ou bien la taille des caractères (en octets). p et e pointent au début et à la fin de la chaîne.
Vérifier de (char*)p à (char*)e-1 .
|
ismbhead(c) | Vrai (Trueà si c est le premier caractère d'une chaîne multi-byte.
|
mbcharlen(c) | Taille d'une chaîne multi-byte si c est le premier caractère d'une chaîne.
|
MBMAXLEN | Taille en byte du plus grand caractère du jeu de caractère. |
When started with the --log-update=file_name
option, mysqld
writes a log file containing all SQL commands that update data. The file is
written in the data directory and has a name of file_name.#
, where
#
is a number that is incremented each time you execute
mysqladmin refresh
or mysqladmin flush-logs
, the FLUSH
LOGS
statement, or restart the
server.
If you use the --log
or -l
options, the filename is
`hostname.log', and restarts and refreshes do not cause a new log file
to be generated. By default, the mysql.server
script starts the
MySQL server with the -l
option. If you need better
performance when you start using MySQL in a production environment,
you can remove the -l
option from mysql.server
.
Update logging is smart since it logs only statements that really update
data. So an UPDATE
or a DELETE
with a WHERE
that finds no
rows is not written to the log. It even skips UPDATE
statements that
set a column to the value it already has.
If you want to update a database from update log files, you could do the following (assuming your log files have names of the form `file_name.#'):
shell> ls -1 -t -r file_name.[0-9]* | xargs cat | mysql
ls
is used to get all the log files in the right order.
This can be useful if you have to revert to backup files after a crash and you want to redo the updates that occurred between the time of the backup and the crash.
You can also use the update logs when you have a mirrored database on another host and you want to replicate the changes that have been made to the master database.
MySQL itself has a 4G limit on table size, and operating systems have their own file size limits. On Linux, the current limit is 2G; on Solaris 2.5.1, the limit is 4G; on Solaris 2.6, the limit is going to be 1000G. Currently, table sizes are limited to either 4G (the MySQL limit) or the operating system limit, whichever is smaller. To get more than 4G requires some changes to MySQL that are on the TODO. F Liste de voeux pour les versions futures de MySQL (la TODO).
If your big table is going to be read-only, you could use pack_isam
to merge and compress many tables to one. pack_isam
usually
compresses a table by at least 50%, so you can have, in effect, much bigger
tables.
pack_isam
.
Another solution can be the included MERGE library, which allows you to handle a collection of identical tables as one. (Identical in this case means that all tables are created with identical column information.) Currently MERGE can only be used to scan a collection of tables because it doesn't support indexes. We will add indexes to this in the near future.
Vous pouvez accéder aux tailles par défaut des buffers de mysqld
avec la commande suivante :
shell> mysqld --help
Cette commande produit la liste de toutes les options et les variables de mysqld
. La réponse fournit aussi les valeurs par défaut, et devrait ressembler à ceci :
Possible variables for option --set-variable (-O) are: back_log current value: 5 connect_timeout current value: 5 delayed_insert_timeout current value: 300 delayed_insert_limit current value: 100 delayed_queue_size current value: 1000 flush_time current value: 0 join_buffer_size current value: 131072 key_buffer_size current value: 1048540 long_query_time current value: 10 max_allowed_packet current value: 1048576 max_connections current value: 100 max_connect_errors current value: 10 max_delayed_threads current value: 20 max_heap_table_size current value: 16777216 max_join_size current value: 4294967295 max_sort_length current value: 1024 max_tmp_tables current value: 32 net_buffer_length current value: 16384 record_buffer current value: 131072 sort_buffer current value: 2097116 table_cache current value: 64 tmp_table_size current value: 1048576 thread_stack current value: 131072 wait_timeout current value: 28800
Si vous avez un serveur mysqld
en fonctionnement, vous pouvez voir les valeurs réellement utilisées en exécutant la commande suivante :
shell> mysqladmin variables
Toutes les options dont détaillées ci-dessous. Les tailles des buffers et des piles, les longueurs sont toutes données en octets. Vous pouvez ajouter le suffixe ``K'' ou ``M'' pour indiquer kilo-octets or mégaoctets. Par exemple, 16M
représente 16 mégaoctets. La casse du suffixe n'a pas d'importance, et; 16M
et 16m
sont équivalents.
back_log
indique le nombre de connexion qui sont mise en attente, avant que MySQL momentanément cesse de réponse à de nouvelles requêtes. Augmentez la valeur pour accepter un grand nombre de connexions dans un délais très court. En d'autres termes, cette valeur correspond à la taille de la file d'attente de connexions TCP/IP. Votre système d'exploitation a sa propre limite. Sous Unix, le manuel donne plus de détails avec l'entrée listen(2).
Vérifier la documentation de votre OS pour connaître la valeur de cette variable. Affecter à back_log
une valeur plus grande que le maximum accepté par le système sera inefficace.
mysqld
ne réponde une erreur Bad handshake
.
INSERT DELAYED
: si les commandes INSERT
sont trop longues, le thread INSERT DELAYED
se finira.
delayed_insert_limit
lignes, le handler INSERT DELAYED
vérifiera qu'il n'y a aucune commande SELECT
en attente. Si c'est le cas, le handler INSERT DELAYED
sera exécuté avant de continuer.
INSERT DELAYED
. Si la queue est pleine, tout client qui émet une commande INSERT DELAYED
devra attendre qu'une place se libère dans la queue.
flush_time
secondes, toutes les tables seront fermées.(pour libérer des ressources, et synchroniser les tables sur le disque).
key_buffer
est la taille des buffers de bloc d'index. Cela permettra d'accélerer le traitement des commandes DELETE
ou INSERT
sur une table avec de nombreux index. Pour accélerer encore plus la commande, reportez vous à la section LOCK TABLES
time
secondes, le compteur de slow_queries
sera incrémentés.
net_buffer_length
octets, mais il peut croître jusqu'à une taille de max_allowed_packet
octets, au besoin. Cette valeur par défaut est trop petite pour gérer de gros paquets (et probablement ceux-ci sont érronnés). Il vaut mieux augmenter la taille cette colonne pour pouvoir gérer des objets de BLOB
: il faudrait que la valeur de cette option soit aussi grande de le plus grand BLOB
que vous voulez utiliser.
mysqld
. Voir ci-après pour plus de détails sur les pointeurs de fichiers
max_connect_errors
connexions interrompues de la part d'un même hote, toutes les tentatives ultérieures de connexions seront bloquées. Vous pouvez aussi débloquer les hôtes avec la commande FLUSH HOSTS
.
INSERT DELAYED à max_delayed_threads
. Si vous tentez d'insérez des informations dans une nouvelle table après que tous les threads INSERT DELAYED
soient utilisés, l'attribut DELAYED
sera ignoré.
max_join_size
lignes retourne une erreur. Affectez une limite si vos utilisateurs prennent la mauvaise habitude d'exécuter des regroupements de plusieurs millions de lignes.
BLOB
ou TEXT
(Seuls lest max_sort_length
premiers octets de chaque valeurs seront utilisés, le reste sera ignoré).
max_allowed_packet
octets.
sort_buffer
octets. Augmentez cette valeur pour accélerer les clauses ORDER BY
ou GROUP BY
. 18.5 Où MySQL enregistre les fichiers temporaires
mysqld
a besoin. MySQL a besoin de deux pointeurs de fichiers pour chaque table. Voir ci-dessous les remarques à propos de la limite du nombre de pointeur de fichier. Pour des détails concernant le cache des tables, 10.8 Comment MySQL ouvre et ferme les tables.
The table nom_table is full
. Augmentez la valeur de tmp_table_size
pour réaliser des requêtes GROUP BY
plus compliquées.
crash-me
dépendent de cette valeur. La valeur par défaut est généralement suffisante. Benchmarks
.
table_cache, max_connections
et max_tmp_tables
limite le nombre maximal de fichier que le serveur peut avoir ouvert en même temps. Si vous augmentez ces valeurs, vous risquez d'être limité par votre système d'exploitation. Cependant, il est possible d'augmenter le nombre de pointeur de fichier par processus, sur certains systèmes. Consultez la documentation de votre système, car ces manipulations varient beaucoup de l'un à l'autre.
table_cache est lié à max_connections
. Par exemple, pour 200 connexions, vous devez avoir un cache de table d'au moins 200 * n
, avec n
nombre maximum de tables dans un regroupement.
MySQL utilise des algorithmes très efficaces, ce qui permet de le faire tourner avec peut de mémoire. Cependant, pour accélérer les traitement, allouez plus de mémoire à MySQL.
En ayant beaucoup de mémoire, et beaucoup de table, si vous souhaitez de bonne performances, avec un nombre modéré de clients, utilisez une configuration telle que :
shell> safe_mysqld -O key_buffer=16M -O table_cache=128 \ -O sort_buffer=4M -O record_buffer=1M &
Si vous avez peu de mémoire et beaucoup de connexion, utilisez une configuration telle que :
shell> safe_mysqld -O key_buffer=512k -O sort_buffer=100k \ -O record_buffer=100k &
voire même :
shell> safe_mysqld -O key_buffer=512k -O sort_buffer=16k \ -O table_cache=32 -O record_buffer=8k -O net_buffer=1K &
Si le nombre de connexion est vraiment très grand, le système va commencer à swapper, à moins que mysqld
n'ait été configuré pour utiliser très peu de mémoire pour chaque connexion. Bien entendu, mysqld
fonctionne bien mieux si vous avez assez de mémoire pour toutes les connexions.
NB : si vous changez une option de mysqld
, cette dernière ne sera prise en compte qu'à la prochaine instance du serveur.
Pour voir si les changement de paramètres ont été pris en compte, utilisez la commande :
shell> mysqld -O key_buffer=32m --help
Assurez vous que l'option --help
est mise en dernier, sinon les options placées après seront ignorées.
La liste suivante indique la manière dont mysqld
utilise la mémoire. A chaque fois que c'est possible, le nom des variables systèmes adéquates sont cités.
key_buffer
) est partagée par tous les threads; Les autres buffers sont alloués selon les nécessités.
thread_stack
) ; un buffer de connexion (variable net_buffer_length
), et un buffer de résultat (variable net_buffer_length
). Les buffers de connexion et de résultat sont dynamiquement aggrandi jusqu'à la taille maximale de max_allowed_packet
selon les besoins. Quand une requête est en cours d'exécution, une copie de la chaîne de requête est aussi allouée.
record_buffer
).
BLOB
sont stockées sur le disque. Un des problèmes récurent est que si une table stockées en HEAP dépasse la taille de tmp_table_size
, vous obtener une erreur de type The table nom_table is full
. Dans les prochaines versions, les tables temporaires sauvées en mémoire seront automatiquement transférées sur le disque. Pour contourner le problème, vous pouvez augmenter le nombre de tables temporaires avec l'option tmp_table_size
ou avec l'option SQL SQL_BIG_TABLES
dans le programme client. SET OPTION
. Avec MySQL 3.20, la taille maximum des tables temporaires était record_buffer*16
, donc, si vous utilisez cette version, vous devez augmenter la valeur de record_buffer
. Vous pouvez aussi démarrer mysqld
avec l'option --big-tables
pour forcer le stockarge des tables temporaires sur le disque. Cependant, cela va affecter les performances des requêtes compliquées.
n
la taille maximum d'une ligne, hormis les BLOB
). Un objet BLOB
ustilise 5 à 8 octets plus la taille des données de l'objet BLOB
.
BLOB
, un buffer est automatiquement aggrandi pour pouvoir lire les grands objets BLOB
. Si vous scannez une table, un buffer aussi grand que le plus grand des objets BLOB
sera alloué.
mysqladmin flush-tables
ferme toutes les tables qui ne sont pas en cours d'utilisation, et s'assure que toutes les tables ouvertes seront aussitôt refermées dès que le thread qui les utilisent auront terminé. Cela permettra de libérer l'essentiel de la mémoire.
ps et d'autres programmes rapportent parfois que mysqld
utilise beaucoup de mémoire. Cela peut être du à de nombreuses piles, dans différents threads, à différentes adresses. Par exemple, la version Solaris de ps
compte la mémoire inutilisée entre les piles comme de la mémoire utilisée. Vous pouvez vérifier ceci en vérifiant le swap disponible, avec : swap -s
. Nous avons testé mysqld
avec des détecteurs de fuite de mémoire du commerce, et il n'y a plus de fuites de mémoire.
La plus part des tests suivants ont été menés sous Linux, et avec la suite de test de MySQL, mais les résultats doivent être transposables aux autres systèmes d'exploitation.
L'exécutable le plus rapide est obtenu avec l'option de link -static
. Utiliser des sockets Unix plutôt que TCP/IP pour se connecter à la base de données est aussi plus efficace.
Avec Linux, l'exécutable le plus rapide fut obtenu en compilant avec pgcc
et -O6
. Pour compiler ``sql_yacc.cc'' avec ces options, vous aurez besoin de 180Mo de méoire, car gcc/pgcc
requiert beaucoup de mémoire pour rendre toutes les fonctions inline. Vous devriez aussi utiliser l'option CXX=gcc
lors de la configuration de MySQL pour éviter l'inclusion de la bibliothèque libstdc++
.
pgcc
et compilez tout avec -O6
, le serveur MySQL sera 11% plus rapide qu'avec gcc
.
-static
), le résultat est 13% plus lent.
gcc
2.7.3 est 13% plus rapide que Sun Pro C++ 4.2.
La distribution MySQL-Linux fournie pas TcX est compilée avec pgcc
et linkée statiquement.
Tous les index (PRIMARY
, UNIQUE
et INDEX()
) sont stockés dans des B-trees. Les chaînes sont automatiquement compressées :
CREATE INDEX
.
Les index sont utilisés pour :
WHERE.
MAX()
ou MIN()
d'une clé donnée
ORDER BY key_part_1,key_part_2
). La clé sont lus dans l'autre sens si on utilise l'attribue DESC
.
Supposons que vous voulez exécuter la commande SELECT
suivante :
mysql> SELECT * FROM nom_table WHERE col1=val1 AND col2=val2;
Si un index multi-colonne existe avec col1
et col2
, les lignes adéquates peuvent être retrouvée directement. Si des index existe sur les colonnes col1
et col2
, l'optimiseur décide quel index va retourner le moins de lignes, et utilise cet index pour retourner les lignes.
Si la table a des index multi-colonnes, tous les prefixes à gauches de l'index peut être utilisé par l'optimiseur pour retrouver les lignes. Par exemple, si vous avez un index de trois colonnes (col1,col2,col3)
, vous avez la possibilité de rechercher rapidement sur les colonnes (col1)
, (col1,col2)
et (col1,col2,col3)
.
MySQL ne peut pas utiliser un index partiel si les colonnes ne forment pas la partie gauche d'un préfixe d'index. Supposons que vous ayez la commande suivante :
mysql> SELECT * FROM nom_table WHERE col1=val1; mysql> SELECT * FROM nom_table WHERE col2=val2; mysql> SELECT * FROM nom_table WHERE col2=val2 AND col3=val3;
Si un index existe sur les colonnes (col1,col2,col3)
, alors seule la première requête utilisera un index. Les deux autres requête font appel à des colonnes indexées, mais (col2)
et (col2,col3)
ne sont pas les préfixes à gauche de (col1,col2,col3)
.
MySQL utilise aussi des index pour des comparaisons de type LIKE
si l'argument de LIKE
est une chaîne constante qui ne commence pas par un caractère spécial. Par exemple, la commande suivante SELECT
utilise des index :
mysql> select * from nom_table where key_col LIKE "Patrick%"; mysql> select * from nom_table where key_col LIKE "Pat%_ck%";
Dans la première commande, seule les lignes "Patrick" <= key_col < "Patricl"
sont prises en considération. Dans la deuxième commande, seule les lignes avec "Pat" <= key_col < "Pau"
sont prises en considération.
Les commandes suivantes ne vont pas utiliser d'index :
mysql> select * from nom_table where key_col LIKE "%Patrick%"; mysql> select * from nom_table where key_col LIKE other_col;
Dans la première, la clause LIKE
commence par un caractère spécial. Dans la deuxième, la clause LIKE
n'est pas constante.
Effectuer des recherches en utilisant column_name IS NULL
utilisera des index si column_name est un index.
MySQL utilise prioritairement des index qui vont trouver le minimum de ligne. Un index est utilisé lors des comparaisons qui impliquent une colonne et un opérateur =
, >
, >=
, <
, <=
, BETWEEN
ou LIKE
sans caractère spécial comme 'quelquechose%'
.
Un index qui ne comprend pas toutes les colonnes utilisées dans une clause WHERE
avec un opérateur AND
n'est pas utilisé pour optimiser la requête.
Les requêtes suivantes utilisent des index :
... WHERE index_part1=1 AND index_part2=2 ... WHERE index=1 OR A=10 AND index=2 /* index = 1 OR index = 2 */ ... WHERE index_part1='hello' AND index_part_3=5 /* optimized like "index_part1='hello'" */
Les requêtes suivantes n'utilisent pas d'index :
... WHERE index_part2=1 AND index_part3=2 /* index_part_1 is not used */ ... WHERE index=1 OR A=10 /* No index */ ... WHERE index_part1=1 OR index_part2=10 /* No index spans all rows */
WHERE
(Cette section est incomplète, car MySQL effectue de nombreuses optimisations.)
En général, lorsque vous voulez accélérer le traitement d'une commande SELECT ... WHERE
, le premier reflexe a avoir est de regarder si il n'est pas possible d'ajouter un index. Toutes les références entre tables devraient utiliser des index. Vous pouvez utiliser la commande EXPLAIN
déterminer quels index sont utilisés au cours d'une commande SELECT
. EXPLAIN
.
Une partie des optimisations de MySQL sont présentées ci-dessous :
((a AND b) AND c OR (((a AND b) AND (c AND d)))) -> (a AND b AND c) OR (a AND b AND c AND d)
(a<b AND b=c) AND a=5 -> b>5 AND b=c AND a=5
(B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6) -> B=5 OR B=6
WHERE
est directement lu dans les informations de la table. C'est aussi vrai pour les expression NOT NULL
utilisé sur une seule table.
SELECT
sont impossibles et retourne aucune ligne.
WHERE
si vous n'utilisez pas GROUP BY
ou des fonctions de groupage, telles que COUNT()
, MIN()
...
WHERE
plus simple est constituée, pour accélérer l'exécution et abandonner les requêtes les plus tôt possible.
WHERE
avec un index UNIQUE
ou une PRIMARY KEY
, et si toutes les membres de l'index sont utilisé avec des expressions constantes.
Toutes les tables suivantes sont utilisées comme des tables constantes :
mysql> SELECT * FROM t WHERE primary_key=1; mysql> SELECT * FROM t1,t2 WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
ORDER BY
et GROUP BY
proviennent de la même table, alors cette table est traitée en premier, lors du regroupement) .
ORDER BY
et une clause GROUP BY
différente, ou si ORDER BY
ou GROUP BY
contiennent des colonnes d'autres tables que la première table dans la commande de regroupement, une table temporaire est créée.
SQL_SMALL_RESULT
, MySQL utilisera une table temporaire en mémoire.
DISTINCT
est convertie en GROUP BY
sur toutes les colonnes, DISTINCT
combiné avec ORDER BY
nécessitera la plus part du temps une table temporaire.
HAVING
sont ignorés.
Quelques exemples de requête très rapides :
mysql> SELECT COUNT(*) FROM nom_table; mysql> SELECT MIN(key_part1),MAX(key_part1) FROM nom_table; mysql> SELECT MAX(key_part2) FROM nom_table WHERE key_part_1=constant; mysql> SELECT ... FROM nom_table ORDER BY key_part1,key_part2,... LIMIT 10; mysql> SELECT ... FROM nom_table ORDER BY key_part1 DESC,key_part2 DESC,... LIMIT 10;
Les requête suivantes sont résolues en utilisant uniquement l'arbre d'index (on supposera que toutes les colonnes indexées sont numériques)
mysql> SELECT key_part1,key_part2 FROM nom_table WHERE key_part1=val; mysql> SELECT COUNT(*) FROM nom_table WHERE key_part1=val1 AND key_part2=val2; mysql> SELECT key_part2 FROM nom_table GROUP BY key_part1;
Les requêtes suivantes sont indexées pour retourner les lignes classées, sans nécessiter de clause de classement :
mysql> SELECT ... FROM nom_table ORDER BY key_part1,key_part2,... mysql> SELECT ... FROM nom_table ORDER BY key_part1 DESC,key_part2 DESC,...
LEFT JOIN
Avec MySQL, les commanndes LEFT JOIN B
sont implémentées comme suit :
B
est marquée comme étant dépendante de la table A
.
A
est marquée comme étant dépendante de toutes les tables (sauf B
) qui sont utilisées dans la condition LEFT JOIN
.
LEFT JOIN
sont transformées en clause WHERE
.
WHERE
sont effectuées.
A
satisfait la clause WHERE
, mais qu'il n'y a aucuen ligne dans la table B
pour satisfaire la condition LEFT JOIN
, alors une nouvelle ligne est générée dans B
avec toutes ses valeurs mises à NULL
.
LEFT JOIN
pour rechercher des lignes qui n'existent pas dans uen table, et que vous avez le test suivant : column_name IS NULL
dans la clause WHERE
, où column_name est une colonne déclarée NOT NULL
, alors MySQL
arrêtera de cherche d'autres lignes (pour une combinaison particulière de clés) dès qu'il aura trouvé une ligne qui satisfait la condition LEFT JOIN
.
LIMIT
Dans certains cas, MySQL va traiter la requête de manière très différente suivant que vous utilisez LIMIT #
et non pas HAVING
:
LIMIT
, MySQL utilisera des index, alors qu'il préfère généralement une recherche exhaustive dans la table.
LIMIT #
avec ORDER BY
, MySQL arrêtera le tri dès qu'il a trouver un nombre suffisant de colonnes, et non pas après avoir scanné la table complète.
LIMIT #
et DISTINCT
, MySQL s'arrête dès qu'il a trouvé #
lignes uniques.
MySQL
a envoyé les premières #
au client, il termine la requête.
Le cache des tables ouvertes peut grossir jusqu'au maximum de table_cache
(par défaut 64; mais cela peut être changé avec l'option -O table_cache=#
de mysqld
). Une table n'est jamais fermé, sauf si le cache est plein, et qu'un thread essaie d'ouvrir une autre table, ou si vous utilisez mysqladmin refresh
ou mysqladmin flush-tables
.
Lorsque le cache de table ouverte se remplit, le serveur utilise les règles suivantes pour localiser la prochaine entrée à utiliser :
Une table est ouverte à chaque accès concurrent. Cela signifie que si vous avez deux threads qui accèdent en même temps à une table, ou accèdent deux fois à une table dans la même requête ( avec AS
), la table sera ouverte deux fois. La première ouverture d'une table requière deux pointeurs de fichiers, et chaque accès supplémentaire n'en demande qu'un de plus. Le deuxième pointeur de fichier ouvert lors de la première ouverture est pour le fichier d'index, et de pointeur est partagé entre tous les autres threads.
Si vous avez trop de fichier dans un dossier, ouvrir, fermer et évaluer des opérations se fera lentement. Si vous exécutez une commande SELECT
sur de nombreuses tables, il ne restera plus beaucoup de marge de manßuvre lorsque le cache sera plein, et cela ralentira nettement les exécutions, puisque pour chaque table à ouvrir, il faut qu'une autre se libère. Vous pouvez réduire ces latences en augmentant la taille du cache.
Lorsque vous exécutez mysqladmin status
, vous verrez quelque chose comme ça :
Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12
Ce qui peut être étrange, surtout si vous n'avez que 6 tables.
MySQL est multi-threadé, ce qui fait que plusieurs requêtes peuvent accéder à la même table en même temps. Pour simplifier le problème, prenons deux threads dans deux états différents, qui accèdent au même fichier. La table est alors ouverte deux fois. Cela requiert de la mémoire et un pointeur de fichier de plus pour le fichier de données. Le pointeur de fichier d'index est partagé par tous les threads.
Vous pouvez déplacer des tables et des bases de données depuis le dossier des bases de données vers n'importe quelle autre place, et les remplacer par des liens symboliques. Cela permet d'implanter les bases dans des systèmes avec plus de place.
Lorsque MySQL remarque qu'une table est un lien symbolique, il va le résoudre et utiliser à la place la table. Cela fonctionne sur tous les systèmes qui acceptent l'appel système realpath()
(par exemple : Linux Solaris supportent realpath()
)! Sur tous les système qui ne supportent pas realpath()
, vous ne devez pas accéder à la table via le chemin et via le lien en même temps. Si vous le faites, la table sera laissée dans un état incohérent.
Par défaut, MySQL n'accepte pas les liens symboliques de bases de données. Les choses tournent mal lorsque vous commencez à faire des liens symboliques entre les bases de données. Supposons que vous ayez une base de db1
dans le dossier de données de MySQL, et que vous créez un lien symbolique db2
qui pointe sur db1
:
shell> cd /path/to/datadir shell> ln -s db1 db2
Maintenant, toute table tbl_a
de db1
est aussi une table tbl_a
de db2
. Si un thread met à jour db1.tbl_a
et un autre thread met à jours db2.tbl_a
, il va y avoir des problèmes de cohérence.
Si vous avez vraiment besoin de cette fonctionnalité, vous devrez changer le code suivant dans ``mysys/mf_format.c'':
if (!lstat(to,&stat_buff)) /* Check if it's a symbolic link */ if (S_ISLNK(stat_buff.st_mode) && realpath(to,buff))
Remplacez le par :
if (realpath(to,buff))
La gestion des verrous sous MySQL est inblocable. Cela est réalisé en demandant toujours tous les droits, en même temps, au début de la requête, et en verrouillant toujours les tables dans le même ordre.
La méthode de verrouillage pour les verrous en écriture (WRITE
) est la suivante :
La méthode de verrouillage pour les verrous en lecture (READ
) est la suivante :
Quand un verrou est libéré, le verrou est rendu disponible pour les threads de la queue d'attente d'écriture, puis dans la queue d'attente de lecture.
Cela signifie que si vous avez de nombreuses modifications sur une table, les commandes SELECT
devront attente qu'il n'ya ait plus de modifications en attente pour être satisfaites.
Pour éviter ce genre de problème, vous pouvez rassembler toutes vos insertions dans une table temporaire, et faire une mise à jour importante de toute la table temporaire dans la fixe, une fois de temps en temps. Cela se réalise avec le code suivant :
mysql> LOCK TABLES real_table WRITE, insert_table WRITE; mysql> insert into real_table select * from insert_table; mysql> delete from insert_table; mysql> UNLOCK TABLES;
Vous pouvez utiliser l'option LOW_PRIORITY
ou HIGH_PRIORITY
avec INSERT
si vous voulez exploiter les priorités. INSERT
.
Vous pouvez aussi changer la procédure de verrouillage dans le fichier ``mysys/thr_lock.c'' pour n'utiliser qu'une seule queue d'attente. Danx ce cas, les verrous d'écriture et de lecture auront les mêmes priorités, ce qui peut être utile dans certains cas.
Vous pouvez accélerer le traitement et minimiser l'espace de stockage d'une table en utilisant les techniques suivantes :
NOT NULL
si possible. Cela accélère l'ensemble, et vous économisez un bit par colonne
TIMESTAMP
ou de type AUTO_INCREMENT
lors d'une commande INSERT
.
mysql_insert_id()
.
MEDIUMINT
est souvent plus efficace que INT
.
VARCHAR
, TEXT
ou BLOB
), la ligne est de longueur fixe. Cela nettement plus rapide, mais cela peut gaspiller un peu de place .
10.17 Quel sont les différents formats de lignes? Quand utiliser VARCHAR/CHAR
?.
isamchk --analyze
sur une table, après l'avoir chargée avec les données adéquates. Cela met à jours une caractéristiques de la table, qui indique le nombre moyen de ligne qui ont la même valeur. (Pour les index uniques, cette valeur vaudra 1, bien entendu).
isamchk --sort-index --sort-records=1
(pour trier avec l'index 1). Si vous avez un index unique dont vous voulez lire toutes lignes dans l'ordre de l'index, c'est une bonne idée pour accélèrer la requête. Remarquez bien que ce classement n'est pas optimal, et qu'il peut s'avérer long pour une grande table.
INSERT
, utilisez des insertions multiples. C'est beaucoup plus rapide que de faire des insertions séparées.
LOAD DATA INFILE
. Cette commande est généralement 20 fois plus rapide que des commandes INSERT
repétées. LOAD DATA
.
Vous pouvez même gagner encore plus de vitesse en chargeant les données dans une table avec de nombreux index en utilisant la procédure suivante :
mysql
ou Perl avec CREATE TABLE
.
mysqladmin flush-tables
.
isamchk --keys-used=0 -rq /path/to/db/nom_table
. Cela va effacer tous les index de cette table.
LOAD DATA INFILE
.
pack_isam
et voulez compresser les tables, lancez pack_isam
.
isamchk -r -q /path/to/db/nom_table
.
mysqladmin flush-tables
.
LOAD DATA INFILE
et INSERT
, agrandissez le buffer de clés. Cela peut se faire avec l'option -O key_buffer=#
option de mysqld
ou safe_mysqld
. Par exemple, 16M est une bonne valeur si vous disposez de beaucoup de RAM
SELECT ... INTO OUTFILE
. Reportez vous à la section LOAD DATA
.
LOCK TABLES
. LOAD DATA INFILE
et SELECT ...INTO OUTFILE
sont atomique, ce qui rend inutile l'utilisation de LOCK TABLES
lors de leur utilisation. LOCK TABLES
.
Pour vérifier l'état de fragmentation de vos tables, utilisez isamchk -evi
sur le fichier``.ISM''. Reportez vous à la section 13 Maintenance d'un serveur MySQL
Le système de verrouillage des tables de MySQL empêche les blocages.
MySQL utilise le verrouillage de table pour réaliser des verrous à très haute vitesse. Cela remplace avantageusement le verrouillage de colonne ou de ligne. Pour les grandes tables, le verrouillage est BEAUCOUP plus rapide que le verrouillage de ligne. Cependant, il y a quelques limitations.
Le verrouillage de table permet à plusieurs threads de lire une table en même temps, mais limite l'écriture de cette table à un seul thread, qui doit s'assurer de l'accès exclusif à la table. Durant la modification, les autres threads devront attendre.
Etant donné que les modifications sont considérés comme plus importantes que les SELECT
, toutes les commandes de modifications ont une priorité supérieure aux commandes de selections. Cela permet de ne pas bloquer les modifications si une table est sujette à un fort trafic en lecture.
Le problème principal avec ceci est décrit avec la situation suivante :
SELECT
qui prend un très long temps.
INSERT
sur la même table; ce client va devoir attendre que le premier a fini.
SELECT
sur la même table; Comme INSERT
a la priorité sur SELECT
, ce SELECT
va attendre que INSERT
soit fini. Il va aussi attendre que le premier SELECT
soit fini !
Les solutions envisageables sont :
SELECT
; comme par exemple, en créant une table sommaire.
mysqld
avec --low-priority-inserts
. Cela va donner aux commandes de sélection la priorité sur les commandes d'insertion. Dans ce cas, la dernière requête SELECT
du scénario passera en priorité sur la commande d'insertion.
INSERT
,UPDATE
ou DELETE
une priorité inférieure avec l'attribut LOW_PRIORITY
.
SET SQL_LOW_PRIORITY_UPDATES=1
. Reportez vous à la section SET OPTION
.
SELECT
une priorité supérieure avec l'attribut HIGH_PRIORITY
. Reportez vous à la section SELECT
.
INSERT
et SELECT
, l'attribut DELAYED
de INSERT
pourra vous aider à résoudre votre problème. Reportez vous à la section INSERT
.
SELECT
et DELETE
, l'option LIMIT
de DELETE
peut être utile. Reportez vous à la section DELETE
.
INSERT
Le temps nécessaire pour insérer une ligne comprend :
Le (nombre) est proportonnel au temps.. Le détail ci-dessus ne prend pas en compte le temps d'ouverture initial des tables (qui sera fait à chaque nouvel accès d'une requête).
Ma taille d'une table ralenti l'insertion des index au rythme de N log N (B-tree).
Vous pouvez accélèrer les insertions en verrouillant votre table et/ou en utilisant des insertions multiples. Les insertions multiples peuvent être jusqu'à 5 fois plus rapides que des insertions séparées :
mysql> LOCK TABLES a WRITE; mysql> INSERT INTO a VALUES (1,23),(2,34),(4,33); mysql> INSERT INTO a VALUES (8,26),(6,29); mysql> UNLOCK TABLES;
La principale différence vient du fait que le buffer d'index est écrit sur le disque une seule fois, après toutes les insertions. Dans l'autre cas, il y aurait de nombreuses écritures sur le disque, une par commande INSERT
. Le verrouillage n'est pas nécessaire si vous pouvez insérer toutes les lignes dans une seule commande d'insertion.
Le verrouillage va aussi réduire le nombre de test de connexions multiples, mais il va aussi augmenter le temps d'attente des autres threads. Par exemple :
thread 1 does 1000 inserts thread 2, 3, and 4 does 1 insert thread 5 does 1000 inserts
Si vous n'utilisez pas le verrouillage, , 2, 3 et 4 vont s'achever avant 1 et 5. Si vous utilisez le verrouillage, 2, 3 et 4 ne vont probablement pas finir avant 1 ou5, mais le temps total devrait être réduit de 40%.
Etant donné que les commandes INSERT
, UPDATE
et DELETE
sont extrêmement rapide sous MySQL, vous obtiendrez une performance générale accrue si vous utilisez le verrouillage dès que vous mettez en jeu plus de 5 commandes. Vous pouvez aussi déverrouiller et reverrouiller une table de temps à autre (si vous inserez énormément de lignes, par exemple), pour donner un peu de temps aux autres threads. Cela peut fournir un gain significatif de performances.
Bien entendu, LOAD DATA INFILE
est toujours le plus efficace.
Si vous insérez de nombreuses lignes de différents clients, vous pouvez accélérer la procédure en utilisant l'option INSERT DELAYED
. INSERT
.
DELETE
Le temps d'effacement est exactement proportionnel au nombre d'index. Pour effacer des lignes plus rapidement, vous pouvez augmenter la taille du cache d'index. La valeur par défaut est 1M; et pour accélérer MySQL, vous devez l'augmenter de plusieurs fois cette valeur( Essayez 16M si vous avez assez de mémoire)
Commencez par tester votre installation ! Vous pouvez prendre n'importe quel programme de la suite de test MySQL (normalement fournie dans le dossier ``sql-bench'') et la modifier selon vos besoin. Vous pourrez ainsi essayer différentes solutions, et trouver celle qui est le plus rapide :
mysqld
avec les options adéquates. Plus de mémoire accélère MySQL, si vous en avez.. 10.1 Optimisation des valeurs du serveur.
NOT NULL
si possible. 10.12 Comment constituer une table pour qu'elle soit petite et rapide?.
isamchk
pour vérifier les tables sans arrêter le serveur mysqld
. L'option --skip-locking
désactive le verrouillage externe entre deux requête SQL. Cela accélère les traitements mais il y a des inconvénients :
mysqladmin flush-tables
avec de vérifier et réparer des tables avec isamchk
. (isamchk -d nom_table
est toujours autorisé, car c'est un simple affichage d'informations).
L'option --skip-locking
est mise par défaut lors de la compilation avec MIT-pthreads, car flock()
n'est pas supporté par MIT-pthreads sur toutes les plate-formes. Le seul ca où il est impossible d'utiliser --skip-locking
est lorsque vous avez plusieurs SERVEUR MySQL (pas les clients) avec les mêmes données (ou bien exécutez isamchk
sur une table sans avoir vidé les tables de la mémoire). Vous pouvez toujours utiliser use LOCK TABLES
/ UNLOCK TABLES
même si vous avec mis l'option --skip-locking
Si votre problème porte sur une fonction particulière de MySQL, vous pouvez toujours la chronométrer avec le client MySQL:
mysql> select benchmark(1000000,1+1); +------------------------+ | benchmark(1000000,1+1) | +------------------------+ | 0 | +------------------------+ 1 row in set (0.32 sec)
L'exemple ci dessus montre que MySQL peut exécuter plus de 1,000,000 de fois l'expressions en 0.32 seconde sur un simple PentiumII 400MHz
.
Toutes les fonctions MySQL sont très optimisées ; mais il peut y avoir des exceptions, et l'utilitaire benchmark(loop_count,expression)
est un bon outil pour étudier votre problème.
VARCHAR/CHAR
?
MySQL n'a pas de type SQL VARCHAR
à proprement parler.
A la place, , MySQL possède trois manières d'enregistrer les informations, et d'émuler le type VARCHAR
.
Si une table n'a aucune colonne de type VARCHAR
, BLOB
ou TEXT
, la table est considéré à taille de ligne constante. Sinon, c'est une ligne à taille variable. Les colonnes CHAR
et VARCHAR
sont alors traitées de manière identique du point de vue de l'application : dans les deux cas, les espaces de fin de chaînes sont supprimés à la lecture.
Vous pouvez vérifier le format utilisé dans une table avec isamchk -d
(-d
signifie ``description de la table``).
MySQL possède trois formats de tables différents : taille fixe, taille variable, compressé. En voici la comparaison :
Tables à taille fixe
VARCHAR
, BLOB
ou TEXT
.
CHAR
, NUMERIC
et DECIMAL
sont complétée par des espaces pour remplir la colonne
isamchk
) à moins q'un nombre important d'enregistrement ne soit effacé, et que vous vouliez libérer de l'espace disque pour le serveur.
Tables à taille variable
VARCHAR
, BLOB
ou TEXT
.
''
), ou nulle (suivant le type de la colonne). (Ne pas confondre avec les valeurs NULL
). Si une colonne de type chaîne a une longueur de 0 après suppression des espaces de remplissage, ou bien si une colonne de type numérique à une valeur de 0, cette information est reportée dans cet octet, et la valeur n'est pas sauvée. Les chaînes non vides ont une longueur d'un octet de plus que le nombre de caractères qu'elles contiennent.
isamchk -r
de temps en temps pour améliorer les performances d'ensemble. Utilisez isamchk -ei nom_table
pour avoir des informations concernant la fragmentation d'une table.
3 + (nombre de colonnes + 7) / 8 + (nombre de colonne de type char) + taille compactee des colonnes de type numerique + longueur des chaînes + (nombre de valeur NULL + 7) / 8
Il y a aussi une pénalité de 6 octet pour chaque fragment de record. Un record de taille variable est fragmenté à chaque fois qu'il grandit de taille. Chaque nouveau fragment prendra au moins 20 octets, ce qui fait que plusieurs aggrandissements pourront partager le même fragment. Sinon, un autre fragment sera généré. Vous pouvez compter le nombre de fragment avec la commande isamchk -ed
. Tous ces fragments peuvent être supprimés avec isamchk -r
.
Table compressée
pack_isam
. Tous les clients avec une garantie étendue par email ont droit à une copie de l'utilitaire pack_isam
pour leur utilisation personnelle.
pack_isam
(ATTENTION : la comrpession est plate forme dépendante.)
0)
sont stockés sur un bit.
BIGINT
(8 octets) peut être stocké au format TINYINT
(1 octet) si sa valeur est entre 0
et 255
.
ENUM
.
BLOB
ou TEXT
.
isamchk
.
MySQL peut supporter différents types d'index, mais le format standard est NISAM. C'est un index de type B-tree dont on peut grossièrement calculer la taille avec la formule (key_length+4)*0.67
, appliquée à toutes les clés. (Ce qui correspond au pire cas, quand toutes les clés sont insérée en ordre).
Les index de chaînes subissent une compression sur les espaces. Si la première partie de l'index est une chaîne, elle sera aussi compressée. La compression des espaces réduit la taille si la colonne a beaucoup d'espace de remplissage, ou si une colonne de type VARCHAR
n'est pas toujours remplie. La compression par préfixe est particulièrement utile si plusieurs chaînes commencent de même.
Les types de table ont été introduit à partir de MySQL 3.23!
Lors de la création d'une table, vous pouvez préciser à MySQL quel type de table utiliser. MySQL va, dans tous les cas, créer un fichier .frm
pour y noter la structure de la table, et les définitions des colonnes. Suivant le type de table, l'index et les données seront enregistrées dans d'autres fichiers.
Vous pouvez convertir des tables d'un type à l'autre avec la commande ALTER TABLE
. Reportez vous à la section ALTER TABLE
.
ISAM
Ce type est le type original de pour les tables MySQL. Il utilise un index B-tree
. L'index est enregistré dans un fichier avec l'extension.ISM
et les données sont enregistrées dans un fichier avec l'extension .ISD
. Vous pouvez vérifier et réparer les tables ISAM
avec l'utilitaire isamchk
. Reportez vous à la section 13.4 Utiliser isamchk
pour réparer une table. Les tables ISAM
ne are sont pas portables d'une plate forme à l'autre. Les fichiers ISAM
ont les caractéristiques suivantes :
MyISAM
est le type de table par défaut à partir de MySQL 3.23. Il est basé sur le code de ISAM
et dispose de nombreuses amélioration : L'index est desormais enregistré dans le fichier .MYI
et les données sont enregistrées dans le fichier .MYD
. Vous pouvez vérifier et réparer des fichiers MyISAM
avec l'utilitaire myisamchk
. 13.4 Utiliser isamchk
pour réparer une table. Les caractéristiques suivantes sont nouvelles:
MyISAM
est donc indépendant de la machine et de l'OS.
AUTO_INCREMENT
. MyISAM
va automatiquement mettre à jour ces colonnes lors des commandes INSERT/UPDATE
. Les commandes AUTO_INCREMENT
peuvent être modifiée avec myisamchk
. Tout ceci accélère les traitements sur les colonnes AUTO_INCREMENT
et les anciens numéros ne seront par réutilisé.
myisamchk
.
MyISAM
indique si le fichier a bien été fermé ou non. Cela permettra bientôt de faire des réparation automatiques.
myisamchk
marque les tables.. myisamchk --fast
ne vérifiera que les talbes qui ne sont pas marquées.
myisamchk -a
crée des statistiques sur les parties de clés (et non plus la totalité des clés, comme avec NISAM
).
myisampack
(appelé pack_isam
sous NISAM
) comrpess les colonnes BLOB
et VARCHAR
MyISAM supporte les caractéristiques suivantes, que MySQL sera bientôt capable d'exploiter :
BLOB
et TEXT
peuvent être indexées/
VARCHAR
: Les colonnes de type VARCHAR
commence par une longueur enregistré sur 2octets.
VARCHAR
peut avoir des enregistrements de longueur variable ou fixes.
VARCHAR
et CHAR
peuvent atteindre la taille de 64Ko. Tous les segments de clés on leur propres définitions. Cela permettra à MySQL d'utiliser des langages différents pour chaque colonne.
NULL
sont autorisés dans les colonnes indexées. Cela prend de 0 à 1 octet par clé.
UNIQUE
; Cela va permettre d'avoir l'attribut UNIQUE
pour n'importe quelle combinaison de colonne d'une table. (On ne pourra pas faire de recherche sur ces index).
HEAP
Ces tables utilisent un index hashé est sont enregistrées en mémoire. Cela les rend beaucoup plus rapide, mais si MySQL crashe, toutes les données seront perdues. HEAP
est un bon type pour les tables temporaire !
CREATE TABLE test TYPE=HEAP SELECT ip,SUM(downloads) as down FROM log_table GROUP BY ip; SELECT COUNT(ip),AVG(down) from test; drop table test;
Voici quelques considérations sur les tables HEAP
:
MAX_ROWS
) dans la commande CREATE
pour s'assurer que la table ne prend pas toute la mémoire.
=
et <=>
(mais TRES rapide )
HEAP
est une table à enregistrement de taille fixe.
HEAP
n'accepte pas les types BLOB/TEXT
.
AUTO_INCREMENT
.
NULL
.
HEAP
(ce qui n'est pas le cas des tables hashées normales)
HEAP
sont partagées entre tous les clients (comme n'importe quelle table)
HEAP
sont allouées par petits blocs. Ces tables sont purement dynamiques en insertion. Pas de dépassement de capacité, ni d'espace de clé supplémentaires à prévoir. Les lignes effacées sont placées dans une liste, et seront réutilisées à la prochaine insertion.
DELETE FROM heap_table
ou DROP TABLE heap_table
.
HEAP
est limitée à max_heap_table_size
.
This should contain a technical description of the MySQL
benchmark suite (and crash-me
) but that description is not
written yet. Currently, you should look at the code and results in the
`bench' directory in the distribution (and of course on the web
page at http://www.mysql.com/crash-me-choose.htmy).
It is meant to be a benchmark that will tell any user what things a given SQL implementation performs well or poorly at.
crash-me
tries to determine what features a database supports and what
its capabilities and limitations are by actually running queries. For
example, it determines:
VARCHAR
column can be
All MySQL clients that communicate with the server using the
mysqlclient
library use the following environment variables:
Name | Description |
MYSQL_UNIX_PORT | The default socket; used for connections to localhost
|
MYSQL_TCP_PORT | The default TCP/IP port |
MYSQL_PWD | The default password |
MYSQL_DEBUG | Debug-trace options when debugging |
TMPDIR | The directory where temporary tables/files are created |
Use of MYSQL_PWD
is insecure.
6.3 Connection au serveur MySQL.
The `mysql' client uses the file named in the MYSQL_HISTFILE
environment variable to save the command line history. The default value for
the history file is `$HOME/.mysql_history', where $HOME
is the
value of the HOME
environment variable.
All MySQL programs take many different options. However, every
MySQL program provides a --help
option that you can use
to get a full description of the program's different options. For example, try
mysql --help
.
You can override default options for all standard client programs with an option file. 4.15.4 Fichier d'options.
The list below briefly describes the MySQL programs:
isamchk
isamchk
has many functions, it is described in its own
chapter.
13 Maintenance d'un serveur MySQL.
make_binary_release
ftp.tcx.se
for the
convenience of other MySQL users.
msql2mysql
mSQL
programs to MySQL. It doesn't
handle all cases, but it gives a good start when converting.
mysql
mysql
is a simple SQL shell (with GNU readline
capabilities).
It supports interactive and non-interactive use. When used interactively,
query results are presented in an ASCII-table format. When used
non-interactively (e.g., as a filter), the result is presented in
tab-separated format. (The output format can be changed using command-line
options.) You can run scripts simply like this:
shell> mysql database < script.sql > output.tabIf you have problems due to insufficient memory in the client, use the
--quick
option! This forces mysql
to use
mysql_use_result()
rather than mysql_store_result()
to retrieve
the result set.
mysqlaccess
mysqladmin
mysqladmin
can also be used to retrieve version,
process and status information from the server.
mysqladmin
.
mysqlbug
mysqld
mysqldump
mysqldump
.
mysqlimport
LOAD DATA
INFILE
. mysqlimport
.
mysqlshow
mysql_install_db
replace
msql2mysql
, but that has more
general applicability as well. replace
changes strings in place in
files or on the standard input. Uses a finite state machine to match longer
strings first. Can be used to swap strings. For example, this command
swaps a
and b
in the given files:
shell> replace a b b a -- file1 file2 ...
safe_mysqld
mysqld
daemon with some safety features, such
as restarting the server when an error occurs and logging runtime information
to a log file.
Utility for performing administrative operations. The syntax is:
shell> mysqladmin [OPTIONS] command [command-option] command ...
You can get a list of the options your version of mysqladmin
supports
by executing mysqladmin --help
.
The current mysqladmin
supports the following commands:
create databasename | Create a new database. |
drop databasename | Delete a database and all its tables. |
extended-status | Gives an extended status message from the server. |
flush-hosts | Flush all cached hosts. |
flush-logs | Flush all logs. |
flush-tables | Flush all tables. |
flush-privileges | Reload grant tables (same as reload) |
kill id,id,... | Kill mysql threads. |
password | new-password Change old password to new-password |
ping | Check if mysqld is alive |
processlist | Show list of active threads in server |
reload | Reload grant tables |
refresh | Flush all tables and close and open logfiles |
shutdown | Take server down |
status | Gives a short status message from the server |
variables | Prints variables available |
version | Get version info from server |
All commands can be shortened to their unique prefix. For example:
shell> mysqladmin proc stat +----+-------+-----------+----+-------------+------+-------+------+ | Id | User | Host | db | Command | Time | State | Info | +----+-------+-----------+----+-------------+------+-------+------+ | 6 | monty | localhost | | Processlist | 0 | | | +----+-------+-----------+----+-------------+------+-------+------+ Uptime: 10077 Threads: 1 Questions: 9 Slow queries: 0 Opens: 6 Flush tables: 1 Open tables: 2 Memory in use: 1092K Max memory used: 1116K
The mysqladmin status
command result has the following columns:
Uptime | Number of seconds the MySQL server have been up |
Threads | Number of active threads (clients) |
Questions | Number of questions from clients since mysqld was started
|
Slow requêtes@tab Requêtesthat has taken more than long_query_time seconds
| |
Opens | How many tables mysqld has opened.
|
Flush tables | Number of flush ... , refresh and reload commands.
|
Open tables | Number of tables that are open now |
Memory in use | Memory allocated directly by the mysqld code (only available when MySQL is compiled with --with-debug) |
Max memory used | Maximum memory allocated directly by the mysqld code (only available when MySQL is compiled with --with-debug) |
Utility to dump a database or a collection of database for backup or for transferring the data to another SQL server. The dump will contain SQL statements to create the table and/or populate the table.
shell> mysqldump [OPTIONS] database [tables]
If you don't give any tables, the whole database will be dumped.
You can get a list of the options your version of mysqldump
supports
by executing mysqldump --help
.
Note that if you run mysqldump
without --quick
or
--opt
, mysqldump
will load the whole result set into
memory before dumping the result. This will probably be a problem if
you are dumping a big database.
mysqldump
supports the following options:
--add-locks
LOCK TABLES
before and UNLOCK TABLE
after each table dump.
(To get faster inserts into MySQL).
--add-drop-table
drop table
before each create statement.
--allow-keywords
-c, --complete-insert
-C, --compress
--delayed
INSERT DELAYED
command.
-e, --extended-insert
INSERT
syntax. (Gives more compact and
faster inserts statements)
-#, --debug[=option_string]
--help
--fields-terminated-by=...
--fields-enclosed-by=...
--fields-optionally-enclosed-by=...
--fields-escaped-by=...
--fields-terminated-by=...
-T
option and have the same
meaning as the corresponding clauses for LOAD DATA INFILE
.
LOAD DATA
.
-F, --flush-logs
-f, --force,
-h, --host=..
localhost
.
-l, --lock-tables.
-t, --no-create-info
CREATE TABLE
statment)
-d, --no-data
--opt
--quick --add-drop-table --add-locks --extended-insert
--use-locks
. Should give you the fastest possible dump for reading
into a MySQL server.
-pyour_pass, --password[=your_pass]
mysqldump
solicits the password from the terminal.
-P port_num, --port=port_num
localhost
, for which Unix sockets are
used.)
-q, --quick
mysql_use_result()
to do this.
-S /path/to/socket, --socket=/path/to/socket
localhost
(which is the
default host).
-T, --tab=path-to-some-directory
table_name.sql
file, that conntains the SQL CREATE commands,
and a table_name.txt
file, that contains the data, for each give table.
NOTE: This only works if mysqldump
is run on the same
machine as the mysqld
daemon. The format of the .txt
file
is made according to the --fields-xxx
and --lines--xxx
options.
-u user_name, --user=user_name
-O var=option, --set-variable var=option
-v, --verbose
-V, --version
-w, --where='where-condition'
"--where=user='jimf'" "-wuserid>1" "-wuserid<1"
The most normal use of mysqldump
is probably for making a backup of
whole database:
mysqldump --opt database > backup-file.sql
But it's also very useful to populate another MySQL server with information from a databas:
mysqldump --opt database | mysql --host=remote-host -C database
mysqlimport
provides a command line interface to the LOAD DATA
INFILE
SQL statement. Most options to mysqlimport
correspond
directly to the same options to LOAD DATA INFILE
.
LOAD DATA
.
mysqlimport
is invoked like this:
shell> mysqlimport [options] filename ...
For each text file named on the command line,
mysqlimport
strips any extension from the filename and uses the result
to determine which table to import the file's contents into. For example,
files named `patient.txt', `patient.text' and `patient' would
all be imported into a table named patient
.
mysqlimport
supports the following options:
-C, --compress
-#, --debug[=option_string]
-d, --delete
--fields-terminated-by=...
--fields-enclosed-by=...
--fields-optionally-enclosed-by=...
--fields-escaped-by=...
--fields-terminated-by=...
LOAD DATA INFILE
. LOAD DATA
.
-f, --force
--force
,
mysqlimport
exits if a table doesn't exist.
--help
-h host_name, --host=host_name
localhost
.
-i, --ignore
--replace
option.
-l, --lock-tables
-L, --local
localhost
(which is the default host).
-pyour_pass, --password[=your_pass]
mysqlimport
solicits the password from the terminal.
-P port_num, --port=port_num
localhost
, for which Unix sockets are
used.)
-r, --replace
--replace
and --ignore
options control handling of input
records that duplicate existing records on unique key values. If you specify
--replace
, new rows replace existing rows that have the same unique key
value. If you specify --ignore
, input rows that duplicate an existing
row on a unique key value are skipped. If you don't specify either option, an
error occurs when a duplicate key value is found, and the rest of the text
file is ignored.
-s, --silent
-S /path/to/socket, --socket=/path/to/socket
localhost
(which is the
default host).
-u user_name, --user=user_name
-v, --verbose
-V, --version
pack_isam
is an extra utility that you get when you order more than 10
licenses or extended support. Since pack_isam
is distributed only in
binary form, pack_isam
is available only on some platforms.
Of course, all future updates to pack_isam
are included in the
price. pack_isam
may at some time be included as standard when
we get some kind of turnover for MySQL.
pack_isam
works by compressing each column in the table separately.
The information needed to decompress columns is read into memory when the
table is opened. This results in much better performance when accessing
individual records, since you only have to uncompress exactly one record, not
a much larger disk block like when using Stacker on MS-DOS.
Usually, pack_isam
packs the data file 40%-70%.
MySQL uses memory mapping (mmap()
) on compressed tables and
falls back to normal read/write file usage if mmap()
doesn't work.
There are currently two limitations with pack_isam
:
BLOB
columns, yet.
Fixing these limitations is on our TODO list but with low priority.
pack_isam
is invoked like this:
shell> pack_isam [options] filename ...
Each filename should be the name of an index (`.ISM') file. If you are not in the database directory, you should specify the pathname to the file. It is permissible to omit the `.ISM' extension.
pack_isam
supports the following options:
-b, --backup
nom_table.OLD
.
-#, --debug=debug_options
debug_options
string often is
'd:t:o,filename'
.
-f, --force
pack_isam
creates a temporary file named `nom_table.TMD'
while it compresses the table. If you kill pack_isam
, the `.TMD'
file may not be deleted. Normally, pack_isam
exits with an error if
it finds that `nom_table.TMD' exists. With --force
,
pack_isam
packs the table anyway.
-?, --help
-j big_nom_table, --join=big_nom_table
big_nom_table
. All tables that are to be combined
MUST be identical (same column names and types, same indexes, etc.)
-p #, --packlength=#
pack_isam
stores all rows with length pointers of 1, 2 or 3
bytes. In most normal cases, pack_isam
can determine the right length
value before it begins packing the file, but it may notice during the packing
process that it could have used a shorter length. In this case,
pack_isam
will print a note that the next time you pack the same file,
you could use a shorter record length.)
-s, --silent
-t, --test
-T dir_name, --tmp_dir=dir_name
-v, --verbose
-V, --version
-w, --wait
mysqld
server was invoked with the --skip-locking
option, it is not a good idea to invoke pack_isam
if the table might
be updated during the packing process.
The sequence of commands shown below illustrates a typical table compression session:
shell> ls -l station.* -rw-rw-r-- 1 monty my 994128 Apr 17 19:00 station.ISD -rw-rw-r-- 1 monty my 53248 Apr 17 19:00 station.ISM -rw-rw-r-- 1 monty my 5767 Apr 17 19:00 station.frm shell> isamchk -dvv station ISAM file: station Isam-version: 2 Creation time: 1996-03-13 10:08:58 Recover time: 1997-02-02 3:06:43 Data records: 1192 Deleted blocks: 0 Datafile: Parts: 1192 Deleted data: 0 Datafile pointer (bytes): 2 Keyfile pointer (bytes): 2 Max datafile length: 54657023 Max keyfile length: 33554431 Recordlength: 834 Record format: Fixed length table description: Key Start Len Index Type Root Blocksize Rec/key 1 2 4 unique unsigned long 1024 1024 1 2 32 30 multip. text 10240 1024 1 Field Start Length Type 1 1 1 2 2 4 3 6 4 4 10 1 5 11 20 6 31 1 7 32 30 8 62 35 9 97 35 10 132 35 11 167 4 12 171 16 13 187 35 14 222 4 15 226 16 16 242 20 17 262 20 18 282 20 19 302 30 20 332 4 21 336 4 22 340 1 23 341 8 24 349 8 25 357 8 26 365 2 27 367 2 28 369 4 29 373 4 30 377 1 31 378 2 32 380 8 33 388 4 34 392 4 35 396 4 36 400 4 37 404 1 38 405 4 39 409 4 40 413 4 41 417 4 42 421 4 43 425 4 44 429 20 45 449 30 46 479 1 47 480 1 48 481 79 49 560 79 50 639 79 51 718 79 52 797 8 53 805 1 54 806 1 55 807 20 56 827 4 57 831 4 shell> pack_isam station.ISM Compressing station.ISM: (1192 records) - Calculating statistics normal: 20 empty-space: 16 empty-zero: 12 empty-fill: 11 pre-space: 0 end-space: 12 table-lookups: 5 zero: 7 Original trees: 57 After join: 17 - Compressing file 87.14% shell> ls -l station.* -rw-rw-r-- 1 monty my 127874 Apr 17 19:00 station.ISD -rw-rw-r-- 1 monty my 55296 Apr 17 19:04 station.ISM -rw-rw-r-- 1 monty my 5767 Apr 17 19:00 station.frm shell> isamchk -dvv station ISAM file: station Isam-version: 2 Creation time: 1996-03-13 10:08:58 Recover time: 1997-04-17 19:04:26 Data records: 1192 Deleted blocks: 0 Datafile: Parts: 1192 Deleted data: 0 Datafilepointer (bytes): 3 Keyfile pointer (bytes): 1 Max datafile length: 16777215 Max keyfile length: 131071 Recordlength: 834 Record format: Compressed table description: Key Start Len Index Type Root Blocksize Rec/key 1 2 4 unique unsigned long 10240 1024 1 2 32 30 multip. text 54272 1024 1 Field Start Length Type Huff tree Bits 1 1 1 constant 1 0 2 2 4 zerofill(1) 2 9 3 6 4 no zeros, zerofill(1) 2 9 4 10 1 3 9 5 11 20 table-lookup 4 0 6 31 1 3 9 7 32 30 no endspace, not_always 5 9 8 62 35 no endspace, not_always, no empty 6 9 9 97 35 no empty 7 9 10 132 35 no endspace, not_always, no empty 6 9 11 167 4 zerofill(1) 2 9 12 171 16 no endspace, not_always, no empty 5 9 13 187 35 no endspace, not_always, no empty 6 9 14 222 4 zerofill(1) 2 9 15 226 16 no endspace, not_always, no empty 5 9 16 242 20 no endspace, not_always 8 9 17 262 20 no endspace, no empty 8 9 18 282 20 no endspace, no empty 5 9 19 302 30 no endspace, no empty 6 9 20 332 4 always zero 2 9 21 336 4 always zero 2 9 22 340 1 3 9 23 341 8 table-lookup 9 0 24 349 8 table-lookup 10 0 25 357 8 always zero 2 9 26 365 2 2 9 27 367 2 no zeros, zerofill(1) 2 9 28 369 4 no zeros, zerofill(1) 2 9 29 373 4 table-lookup 11 0 30 377 1 3 9 31 378 2 no zeros, zerofill(1) 2 9 32 380 8 no zeros 2 9 33 388 4 always zero 2 9 34 392 4 table-lookup 12 0 35 396 4 no zeros, zerofill(1) 13 9 36 400 4 no zeros, zerofill(1) 2 9 37 404 1 2 9 38 405 4 no zeros 2 9 39 409 4 always zero 2 9 40 413 4 no zeros 2 9 41 417 4 always zero 2 9 42 421 4 no zeros 2 9 43 425 4 always zero 2 9 44 429 20 no empty 3 9 45 449 30 no empty 3 9 46 479 1 14 4 47 480 1 14 4 48 481 79 no endspace, no empty 15 9 49 560 79 no empty 2 9 50 639 79 no empty 2 9 51 718 79 no endspace 16 9 52 797 8 no empty 2 9 53 805 1 17 1 54 806 1 3 9 55 807 20 no empty 3 9 56 827 4 no zeros, zerofill(2) 2 9 57 831 4 no zeros, zerofill(1) 2 9
The information printed by pack_isam
is described below:
normal
empty-space
empty-zero
empty-fill
INTEGER
column may be changed to MEDIUMINT
).
pre-space
end-space
table-lookup
ENUM
before Huffman compression.
zero
Original trees
After join
After a table has been compressed, isamchk -dvv
prints additional
information about each field:
Type
constant
no endspace
no endspace, not_always
no endspace, no empty
table-lookup
ENUM
.
zerofill(n)
n
bytes in the value are always 0 and are not
stored.
no zeros
always zero
Huff tree
Bits
isamchk
pour la maintenance et la réparation
Pour vérifier/réparer les tables ISAM (.ISM
et .ISD
), vous devez utiliser
l'utilitaire : isamchk
. Pour vérifier/réparer les tables MyISAM (.MYI
et .MYD
)
vous devez utiliser utiliser l'utilitaire myisamchk
.
10.18 Types de tables MySQL.
Par la suite, nous traiterons le cas de isamchk
mais les instructions pourront
aussi s'appliquer à myisamchk
.
Vous pouvez utiliser l'utilitaire isamchk
pour receuillir des informations sur
votre base de données et ses tables, pour vérifier et réparer les tables ou encore les
optimiser. La section suivante décrit les commandes d'invocations de isamchk
(y compris les options), les méthodes de maintenance régulière, et comment utiliser
isamchk
pour effectuer diverses tàches.
If you run mysqld
with --skip-locking
(which is the default on
some systems, like Linux), you can't reliably use isamchk
to
check a table when mysqld
is using the same table. If you
can be sure that no one is accessing the tables through mysqld
while you run isamchk
, you only have to do mysqladmin
flush-tables
before you start checking the tables. If you can't
guarantee the above, then you must take down mysqld
while you
check the tables. If you run isamchk
while mysqld
is updating
the tables, you may get a warning that a table is corrupt even if it
isn't.
If you are not using --skip-locking
, you can use isamchk
to check tables at any time. While you do this, all clients that try
to update the table will wait until isamchk
is ready before
continuing.
If you use isamchk
to repair or optimize tables, you
MUST always ensure that the mysqld
server is not using
the table (this also applies if you are using --skip-locking
).
If you don't take down mysqld
you should at least do a
mysqladmin flush-tables
before you run isamchk
.
You can in most cases also use the command OPTIMIZE TABLES
to
optimize and repair tables, but this is not as fast or reliable (in case
of real fatal errors) as isamchk
. On the other hand,
OPTIMIZE TABLE
is easier to use and you don't have to worry about
flushing tables.
OPTIMIZE TABLE
.
isamchk
isamchk
is invoked like this:
shell> isamchk [options] nom_table
The options
specify what you want isamchk
to do. They are
described below. (You can also get a list of options by invoking
isamchk --help
.) With no options, isamchk
simply checks your
table. To get more information or to tell isamchk
to take corrective
action, specify options as described below and in the following sections.
nom_table
is the database table you want to check. If you run
isamchk
somewhere other than in the database directory, you must
specify the path to the file, since isamchk
has no idea where your
database is located. Actually, isamchk
doesn't care whether or not
the files you are working on are located in a database directory; you can
copy the files that correspond to a database table into another location and
perform recovery operations on them there.
You can name several tables on the isamchk
command line if you
wish. You can also specify a name as an index file
name (with the `.ISM' suffix), which allows you to specify all
tables in a directory by using the pattern `*.ISM'.
For example, if you are in a database directory, you can check all the
tables in the directory like this:
shell> isamchk *.ISM
If you are not in the database directory, you can check all the tables there by specifying the path to the directory:
shell> isamchk /path/to/database_dir/*.ISM
You can even check all tables in all databases by specifying a wildcard with the path to the MySQL data directory:
shell> isamchk /path/to/datadir/*/*.ISM
isamchk
supports the following options:
-a, --analyze
-#, --debug=debug_options
debug_options
string often is
'd:t:o,filename'
.
-d, --description
-e, --extend-check
isamchk
should find all errors even without this option.
-f, --force
-f
when checking tables (running isamchk
without -r
), isamchk
will automatically restart with -r
on any table for which an error occurs during checking.
--help
-i, --information
-k #, --keys-used=#
-r
. Tell the NISAM table handler to update only the first
#
indexes. Higher-numbered indexes are deactivated. This can be used
to get faster inserts! Deactivated indexes can be reactivated by using
isamchk -r
.
-l, --no-symlinks
isamchk
repairs the table a symlink points at.
-q, --quick
-r
to get a faster repair. Normally, the original data file
isn't touched; you can specify a second -q
to force
the original data file to be used.
-r, --recover
-o, --safe-recover
-r
, but can
handle a couple of cases that -r
cannot handle.
-O var=option, --set-variable var=option
-s, --silent
-s
twice (-ss
) to make isamchk
very silent.
-S, --sort-index
-R index_num, --sort-records=index_num
SELECT
and ORDER BY
operations on
this index. (It may be VERY slow to do a sort the first time!)
To find out a table's index numbers, use SHOW INDEX
, which shows a
table's indexes in the same order that isamchk
sees them. Indexes are
numbered beginning with 1.
-u, --unpack
pack_isam
.
-v, --verbose
-d
and
-e
. Use -v
multiple times (-vv
, -vvv
) for more
verbosity!
-V, --version
isamchk
version and exit.
-w, --wait
Possible variables for the --set-variable
(-O
) option are:
key_buffer_size current value: 16776192 read_buffer_size current value: 262136 write_buffer_size current value: 262136 sort_buffer_size current value: 2097144 sort_key_blocks current value: 16 decode_bits current value: 9
isamchk
Memory allocation is important when you run isamchk
. isamchk
uses no more memory than you specify with the -O
options. If you are
going to use isamchk
on very large files, you should first decide how
much memory you want it to use. The default is to use only about 3M to fix
things. By using larger values, you can get isamchk
to operate
faster. For example, if you have more than 32M RAM, you could use options
such as these (in addition to any other options you might specify):
shell> isamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...
Using -O sort=16M
should
probably be enough for most cases.
Be aware that isamchk
uses temporary files in TMPDIR
. If
TMPDIR
points to a memory file system, you may easily get out of
memory errors. If this happens, set TMPDIR
to point at some directory
with more space and restart isamchk
It is a good idea to perform table checks on a regular basis rather than
waiting for problems to occur. For maintenance purposes, you can use
isamchk -s
to check tables. The -s
option causes
isamchk
to run in silent mode, printing messages only when errors
occur.
It's a good idea to check tables when the server starts up.
For example, whenever the machine has done a reboot in the middle of an
update, you usually need to check all the tables that could have been
affected. (This is an ``expected crashed table''.) You could add a test to
safe_mysqld
that runs isamchk
to check all tables that have
been modified during the last 24 hours if there is an old `.pid'
(process ID) file left after a reboot. (The `.pid' file is created by
mysqld
when it starts up and removed when it terminates normally. The
presence of a `.pid' file at system startup time indicates that
mysqld
terminated abnormally.)
An even better test would be to check any table whose last-modified time is more recent than that of the `.pid' file.
You should also check your tables regularly during normal system operation.
At TcX, we run a cron
job to check all our important tables once a week,
using a line like this in a `crontab' file:
35 0 * * 0 /path/to/isamchk -s /path/to/datadir/*/*.ISM
This prints out information about crashed tables so we can examine and repair them when needed.
As we haven't had any unexpectedly crashed tables (tables that become corrupted for reasons other than hardware trouble) for a couple of years now (this is really true), once a week is more than enough for us.
We recommend that to start with, you execute isamchk -s
each
night on all tables that have been updated during the last 24 hours,
until you come to trust MySQL as much as we do.
To get a description of a table or statistics about it, use the commands shown below. We explain some of the information in more detail later.
isamchk -d nom_table
isamchk
in ``describe mode'' to produce a description of your
table. If you start the MySQL server using the --skip-locking
option, isamchk
may report an error for a table that is updated while
it runs. However, since isamchk
doesn't change the table in describe
mode, there isn't any risk of destroying data.
isamchk -d -v nom_table
isamchk
is doing, add -v
to tell it to run in verbose mode.
isamchk -eis nom_table
isamchk -eiv nom_table
-eis
, but tells you what is being done.
Example of isamchk -d
output:
ISAM file: company.ISM Data records: 1403698 Deleted blocks: 0 Recordlength: 226 Record format: Fixed length table description: Key Start Len Index Type 1 2 8 unique double 2 15 10 multip. text packed stripped 3 219 8 multip. double 4 63 10 multip. text packed stripped 5 167 2 multip. unsigned short 6 177 4 multip. unsigned long 7 155 4 multip. text 8 138 4 multip. unsigned long 9 177 4 multip. unsigned long 193 1 text
Example of isamchk -d -v
output:
ISAM file: company.ISM Isam-version: 2 Creation time: 1996-08-28 11:44:22 Recover time: 1997-01-12 18:35:29 Data records: 1403698 Deleted blocks: 0 Datafile: Parts: 1403698 Deleted data: 0 Datafilepointer (bytes): 3 Keyfile pointer (bytes): 3 Max datafile length: 3791650815 Max keyfile length: 4294967294 Recordlength: 226 Record format: Fixed length table description: Key Start Len Index Type Root Blocksize Rec/key 1 2 8 unique double 15845376 1024 1 2 15 10 multip. text packed stripped 25062400 1024 2 3 219 8 multip. double 40907776 1024 73 4 63 10 multip. text packed stripped 48097280 1024 5 5 167 2 multip. unsigned short 55200768 1024 4840 6 177 4 multip. unsigned long 65145856 1024 1346 7 155 4 multip. text 75090944 1024 4995 8 138 4 multip. unsigned long 85036032 1024 87 9 177 4 multip. unsigned long 96481280 1024 178 193 1 text
Example of isamchk -eis
output:
Checking ISAM file: company.ISM Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4 Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4 Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4 Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3 Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4 Total: Keyblocks used: 98% Packed: 17% Records: 1403698 M.recordlength: 226 Packed: 0% Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00 Recordblocks: 1403698 Deleteblocks: 0 Recorddata: 317235748 Deleted data: 0 Lost space: 0 Linkdata: 0 User time 1626.51, System time 232.36 Maximum resident set size 0, Integral resident set size 0 Non physical pagefaults 0, Physical pagefaults 627, Swaps 0 Blocks in 0 out 0, Messages in 0 out 0, Signals 0 Voluntary context switches 639, Involuntary context switches 28966
Example of isamchk -eiv
output:
Checking ISAM file: company.ISM Data records: 1403698 Deleted blocks: 0 - check file-size - check delete-chain index 1: index 2: index 3: index 4: index 5: index 6: index 7: index 8: index 9: No recordlinks - check index reference - check data record references index: 1 Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4 - check data record references index: 2 Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4 - check data record references index: 3 Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4 - check data record references index: 4 Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3 - check data record references index: 5 Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3 - check data record references index: 6 Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3 - check data record references index: 7 Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3 - check data record references index: 8 Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3 - check data record references index: 9 Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4 Total: Keyblocks used: 9% Packed: 17% - check records and index references [LOTS OF ROW NUMBERS DELETED] Records: 1403698 M.recordlength: 226 Packed: 0% Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00 Recordblocks: 1403698 Deleteblocks: 0 Recorddata: 317235748 Deleted data: 0 Lost space: 0 Linkdata: 0 User time 1639.63, System time 251.61 Maximum resident set size 0, Integral resident set size 0 Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0 Blocks in 4 out 0, Messages in 0 out 0, Signals 0 Voluntary context switches 10604, Involuntary context switches 122798
Here are the sizes of the data and index files for the table used in the preceding examples:
-rw-rw-r-- 1 monty tcx 317235748 Jan 12 17:30 company.ISD -rw-rw-r-- 1 davida tcx 96482304 Jan 12 18:35 company.ISM
Explanations for the types of information isamchk
produces are given
below. The ``keyfile'' is the index file. ``Record'' and ``row'' are
synonymous.
ISAM file
Isam-version
Creation time
Recover time
Data records
Deleted blocks
Datafile: Parts
Data
records
.
Deleted data
Datafile pointer
Keyfile pointer
Max datafile length
.ISD
file) can become, in bytes.
Max keyfile length
.ISM
file) can become, in bytes.
Recordlength
Record format
Fixed length
.
Other possible values are Compressed
and Packed
.
table description
Key
Start
Len
Index
unique
or multip.
(multiple). Indicates whether or not one value
can exist multiple times in this index.
Type
packed
, stripped
or empty
.
Root
Blocksize
Rec/key
isamchk -a
. If this is not updated at all, a default
value of 30 is given.
Keyblocks used
isamchk
, the values are very
high (very near the theoretical maximum).
Packed
CHAR
/VARCHAR
/DECIMAL
keys. For long strings like
names, this can significantly reduce the space used. In the third example
above, the 4th key is 10 characters long and a 60% reduction in space is
achieved.
Max levels
Records
M.recordlength
Packed
Packed
value indicates the percentage savings achieved by doing this.
Recordspace used
Empty space
Blocks/Record
isamchk
.
13.4.3 Optimisation de tables.
Recordblocks
Deleteblocks
Recorddata
Deleted data
Lost space
Linkdata
Linkdata
is the sum of the amount of
storage used by all such pointers.
If a table has been compressed with pack_isam
, isamchk -d
prints additional information about each table column. See pack_isam
, for an example of this information and a description of
what it means.
isamchk
pour réparer une tableThe file format that MySQL uses to store data has been extensively tested, but there are always external circumstances that may cause database tables to become corrupted:
mysqld
process being killed in the middle of a write
This chapter describes how to check for and deal with data corruption in MySQL databases. If your tables get corrupted a lot you should try to find the reason for this! G.1 Debugguer un serveur MySQL.
When performing crash recovery, it is important to understand that each table
nom_table
in a database corresponds to three files in the database
directory:
File | Purpose |
`nom_table.frm' | Table definition (form) file |
`nom_table.ISD' | Data file |
`nom_table.ISM' | Index file |
Each of these three file types is subject to corruption in various ways, but problems occur most often in data files and index files.
isamchk
works by creating a copy of the `.ISD' (data) file row by
row. It ends the repair stage by removing the old `.ISD' file and
renaming the new file to the original file name. If you use --quick
,
isamchk
does not create a temporary `.ISD' file, but instead
assumes that the `.ISD' file is correct and only generates a new index
file without touching the `.ISD' file. This is safe, because
isamchk
automatically detects if the `.ISD' file is corrupt and
aborts the repair in this case. You can also give two --quick
options
to isamchk
. In this case, isamchk
does not abort on some
errors (like duplicate key) but instead tries to resolve them by
modifying the `.ISD' file. Normally the use of two --quick
options is useful only if you have too little free disk space to perform a
normal repair. In this case you should at least make a backup before running
isamchk
.
To check a table, use the following commands:
isamchk nom_table
isamchk
without options or
with either the -s
or --silent
option.
isamchk -e nom_table
-e
means
``extended check''). It does a check-read of every key for each row to verify
that they indeed point to the correct row. This may take a LONG time on a
big table with many keys. isamchk
will normally stop after the first
error it finds. If you want to obtain more information, you can add the
--verbose
(-v
) option. This causes isamchk
to keep
going, up through a maximum of 20 errors. In normal usage, a simple
isamchk
(with no arguments other than the table name) is sufficient.
isamchk -e -i nom_table
-i
option tells isamchk
to
print some informational statistics, too.
The symptoms of a corrupted table are usually that requêtesabort unexpectedly and that you observe errors such as these:
In these cases, you must repair your tables. isamchk
can usually detect and fix most things that go wrong.
The repair process involves up to four stages, described below. Before you
begin, you should cd
to the database directory and check the
permissions of the table files. Make sure they are readable by the Unix user
that mysqld
runs as (and to you, since you need to access the files
you are checking). If it turns out you need to modify files, they must also
be writable by you.
Stage 1: Checking your tables
Run isamchk *.ISM
or (isamchk -e *.ISM
if you have more time).
Use the -s
(silent) option to suppress unnecessary information.
You have to repair only those tables for which isamchk
announces an
error. For such tables, proceed to Stage 2.
If you get weird errors when checking (such as out of
memory
errors), or if isamchk
crashes, go to Stage 3.
Stage 2: Easy safe repair
First, try isamchk -r -q nom_table
(-r -q
means ``quick recovery
mode''). This will attempt to repair the index file without touching the data
file. If the data file contains everything that it should and the delete
links point at the correct locations within the data file, this should work
and the table is fixed. Start repairing the next table. Otherwise, use the
following procedure:
isamchk -r nom_table
(-r
means ``recovery mode''). This will
remove incorrect records and deleted records from the data file and
reconstruct the index file.
isamchk --safe-recover nom_table
.
Safe recovery mode uses an old recovery méthode that handles a few cases that
regular recovery mode doesn't (but is slower).
If you get weird errors when repairing (such as out of
memory
errors), or if isamchk
crashes, go to Stage 3.
Stage 3: Difficult repair
You should only reach this stage if the first 16K block in the index file is destroyed or contains incorrect information, or if the index file is missing. In this case, it's necessary to create a new index file. Do so as follows:
shell> mysql nom_base_de_donnees mysql> DELETE FROM nom_table; mysql> quit
Go back to Stage 2. isamchk -r -q
should work now. (This shouldn't
be an endless loop).
Stage 4: Very difficult repair
You should reach this stage only if the description file has also crashed. That should never happen, because the description file isn't changed after the table is created.
isamchk -r
.
To coalesce fragmented records and eliminate wasted space resulting from
deleting or updating records, run isamchk
in recovery mode:
shell> isamchk -r nom_table
You can optimize a table in the same way using the SQL OPTIMIZE TABLE
statement. OPTIMIZE TABLE
is easier, but isamchk
is faster.
isamchk
also has a number of other options you can use to improve
the performance of a table:
-S, --sort-index
-R index_num, --sort-records=index_num
-a, --analyze
For a full description of the option see 13.1.1 Syntaxe isamchk
.
When using MySQL with log files, you will from time to time want to remove/backup old log files and tell MySQL to start logging on new files. 9.2 Historique de modification.
One a Linux (Redhat
) installation, you can use the
mysql-log-rotate
script for this. If you installed MySQL
from an RPM distribution, the script should have been installed
automatically.
On other systems you must install a short script yourself that you
start from cron
to handle log files.
You can force MySQL to start using new log files by using
mysqladmin flush-logs
or by using the SQL command FLUSH LOGS
.
If you are using MySQL 3.21 you must use mysqladmin refresh
.
The above command does the following:
--log
) is used, closes and reopens the log file.
(`mysql.log' as default).
--log-update
) is used, closes the update log and
opens a new log file with a higher sequence number.
If you are using only an update log, you only have to flush the logs and then move away the old update log files to a backup. If you are using the normal logging, you can do something like:
shell> cd mysql-data-directory shell> mv mysql.log mysql.old shell> mysqladmin flush-tables
and then take a backup and remove `mysql.old'.
There are two ways to add new functions to MySQL:
CREATE FUNCTION
and DROP FUNCTION
statements.
CREATE FUNCTION
.
mysqld
server and become
available on a permanent basis.
Each méthode has advantages and disadvantages:
Whichever méthode you use to add new functions, they may be used just like
native functions such as ABS()
or SOUNDEX()
.
For the UDF mechanism to work, functions must be written in C or C++ and your operating system must support dynamic loading. The MySQL source distribution includes a file `sql/udf_example.cc' that defines 5 new functions. Consult this file to see how UDF calling conventions work.
For each function that you want to use in SQL statements, you should define
corresponding C (or C++) functions. In the discussion below, the name
``xxx'' is used for an example function name. To distinquish between SQL and
C/C++ usage, XXX()
(uppercase) indicates a SQL function call, and
xxx()
(lowercase) indicates a C/C++ function call.
The C/C++ functions that you write to implement the inferface for
XXX()
are:
xxx()
(required)
SQL type | C/C++ type |
STRING | char *
|
INTEGER | long long
|
REAL | double
|
xxx_init()
(optional)
xxx()
. It can be used to:
XXX()
REAL
functions) the maximum number of decimals
NULL
xxx_deinit()
(optional)
xxx()
. It should deallocate any
memory allocated by the initialization function.
When a SQL statement invokes XXX()
, MySQL calls the
initialization function xxx_init()
to let it perform any required
setup, such as argument checking or memory allocation. If xxx_init()
returns an error, the SQL statement is aborted with an error message and the
main and deinitialization functions are not called. Otherwise, the main
function xxx()
is called once for each row. After all rows have been
processed, the deinitialization function xxx_deinit()
is called so it
can perform any required cleanup.
All functions must be thread-safe (not just the main function,
but the initialization and deinitialization functions as well). This means
that you are not allowed to allocate any global or static variables that
change! If you need memory, you should allocate it in xxx_init()
and free it in xxx_deinit()
.
The main function should be declared as shown below. Note that the return
type and parameters differ, depending on whether you will declare the SQL
function XXX()
to return STRING
, INTEGER
or REAL
in the CREATE FUNCTION
statement:
For STRING
functions:
char *xxx(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
For INTEGER
functions:
long long xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
For REAL
functions:
double xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
The initialization and deinitialization functions are declared like this:
my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void xxx_deinit(UDF_INIT *initid);
The initid
parameter is passed to all three functions. It points to a
UDF_INIT
structure that is used to communicate information between
functions. The UDF_INIT
structure members are listed below. The
initialization function should fill in any members that it wishes to change.
(To use the default for a member, leave it unchanged.)
my_bool maybe_null
xxx_init()
should set maybe_null
to 1
if xxx()
can return NULL
. The default value is 1
if any of the
arguments are declared maybe_null
.
unsigned int decimals
1.34
, 1.345
and 1.3
, the default would be 3,
since 1.345
has 3 decimals.
unsigned int max_length
initid->decimals
. (For numeric functions, the length
includes any sign or decimal point characters.)
char *ptr
initid->ptr
to communicate allocated memory
between functions. In xxx_init()
, allocate the memory and assign it
to this pointer:
initid->ptr = allocated_memory;In
xxx()
and xxx_deinit()
, refer to initid->ptr
to use
or deallocate the memory.
The args
parameter points to a UDF_ARGS
structure which has the
members listed below:
unsigned int arg_count
if (args->arg_count != 2) { strcpy(message,"XXX() requires two arguments"); return 1; }
enum Item_result *arg_type
STRING_RESULT
, INT_RESULT
and REAL_RESULT
.
To make sure that arguments are of a given type and return an
error if they are not, check the arg_type
array in the initialization
function. For example:
if (args->arg_type[0] != STRING_RESULT && args->arg_type[1] != INT_RESULT) { strcpy(message,"XXX() requires a string and an integer"); return 1; }As an alternative to requiring your function's arguments to be of particular types, you can use the initialization function to set the
arg_type
elements to the types you want. This causes MySQL to coerce
arguments to those types for each call to xxx()
. For example, to
specify coercion of the first two arguments to string and integer, do this in
xxx_init()
:
args->arg_type[0] = STRING_RESULT; args->arg_type[1] = INT_RESULT;
char **args
args->args
communicates information to the initialization function
about the general nature of the arguments your function was called with. For a
constant argument i
, args->args[i]
points to the argument
value. (See below for instructions on how to access the value properly.)
For a non-constant argument, args->args[i]
is 0
.
A constant argument is an expression that uses only constants, such as
3
or 4*7-2
or SIN(3.14)
. A non-constant argument is an
expression that refers to values that may change from row to row, such as
column names or functions that are called with non-constant arguments.
For each invocation of the main function, args->args
contains the
actual arguments that are passed for the row currently being processed.
Functions can refer to an argument i
as follows:
STRING_RESULT
is given as a string pointer plus a
length, to allow handling of binary data or data of arbitrary length. The
string contents are available as args->args[i]
and the string length
is args->lengths[i]
. You should not assume that strings are
null-terminated.
INT_RESULT
, you must cast
args->args[i]
to a long long
value:
long long int_val; int_val = *((long long*) args->args[i]);
REAL_RESULT
, you must cast
args->args[i]
to a double
value:
double real_val; real_val = *((double*) args->args[i]);
unsigned long *lengths
lengths
array indicates the
maximum string length for each argument. For each invocation of the main
function, lengths
contains the actual lengths of any string arguments
that are passed for the row currently being processed. For arguments of
types INT_RESULT
or REAL_RESULT
, lengths
still contains
the maximum length of the argument (as for the initialization function).
The initialization function should return 0
if no error occurred and
1
otherwise. If an error occurs, xxx_init()
should store a
null-terminated error message in the message
parameter. The message
will be returned to the client. The message buffer is
MYSQL_ERRMSG_SIZE
characters long, but you should try to keep the
message to less than 80 characters so that it fits the width of a standard
terminal screen.
The return value of the main function xxx()
is the function value, for
long long
and double
functions. For string functions, the
string is returned in the result
and length
arguments.
result
is a buffer at least 255 bytes long. Set these to the contents
and length of the return value. For example:
memcpy(result, "result string", 13); *length = 13;
The string function return value normally also points to the result.
To indicate a return value of NULL
in the main function, set
is_null
to 1
:
*is_null = 1;
To indicate an error return in the main function, set the error
parameter to 1
:
*error = 1;
If xxx()
sets *error
to 1
for any row, the function
value is NULL
for the current row and for any subsequent rows
processed by the statement in which XXX()
was invoked. (xxx()
will not even be called for subsequent rows.) Note: In
MySQL versions prior to 3.22.10, you should set both *error
and *is_null
:
*error = 1; *is_null = 1;
Files implementing UDFs must be compiled and installed on the host where the server runs. This process is described below for the example UDF file `udf_example.cc' that is included in the MySQL source distribution. This file contains the following functions:
metaphon()
returns a metaphon string of the string argument.
This is something like a soundex string, but it's more tuned for English.
myfunc_double()
returns the sum of the ASCII values of the
characters in its arguments, divided by the sum of the length of its arguments.
myfunc_int()
returns the sum of the length of its arguments.
lookup()
returns the IP number for a hostname.
reverse_lookup()
returns the hostname for an IP number.
The function may be called with a string "xxx.xxx.xxx.xxx"
or
four numbers.
A dynamically-loadable file should be compiled as a sharable object file, using a command something like this:
shell> gcc -shared -o udf_example.so myfunc.cc
You can easily find out the correct compiler options for your system by running this command in the `sql' directory of your MySQL source tree:
shell> make udf_example.o
You should run a compile command similar to the one that make
displays,
except that you should remove the -c
option near the end of the line
and add -o udf_example.so
to the end of the line. (On some systems,
you may need to leave the -c
on the command.)
Once you compile a shared object containing UDFs, you must install it
and tell MySQL about it. Compiling a shared object from
`udf_example.cc' produces a file named something like
`udf_example.so' (the exact name may vary from platform to platform).
Copy this file to some directory searched by ld
, such as
`/usr/lib'. On many systems, you can set the LD_LIBRARY
or
LD_LIBRARY_PATH
environment variable to point at the directory where
you have your UDF function files. The dopen
manual page tells you
which variable you should use on your system. You should set this in
mysql.server
or safe_mysqld
and restart mysqld
.
After the library is installed, notify mysqld
about the new
functions with these commands:
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so";
Functions can be deleted using DROP FUNCTION
:
mysql> DROP FUNCTION metaphon; mysql> DROP FUNCTION myfunc_double; mysql> DROP FUNCTION myfunc_int; mysql> DROP FUNCTION lookup; mysql> DROP FUNCTION reverse_lookup;
The CREATE FUNCTION
and DROP FUNCTION
statements update the
system table func
in the mysql
database. The function's name,
type and shared library name are saved in the table. You must have the
insert and delete privileges for the mysql
database
to create and drop functions.
You should not use CREATE FUNCTION
to add a function that has already
been created. If you need to reinstall a function, you should remove it with
DROP FUNCTION
and then reinstall it with CREATE FUNCTION
. You
would need to do this, for example, if you recompile a new version of your
function, so that mysqld
gets the new version. Otherwise the server
will continue to use the old version.
Active functions are reloaded each time the server starts, unless you start
mysqld
with the --skip-grant-tables
option. In this case, UDF
initialization is skipped and UDFs are unavailable. (An active function is
one that has been loaded with CREATE FUNCTION
and not removed with
DROP FUNCTION
.)
The procedure for adding a new native function is described below. Note that you cannot add native functions to a binary distribution since the procedure involves modifying MySQL source code. You must compile MySQL yourself from a source distribution. Also note that if you migrate to another version of MySQL (e.g., when a new version is released), you will need to repeat the procedure with the new version.
To add a new native MySQL function, follow these steps:
sql_functions[]
array.
yacc
should define (this should be added at the
beginning of the file). Then define the function parameters and add an
``item'' with these parameters to the simple_expr
parsing rule.
For an example, check all occurrences of SOUNDEX
in
`sql_yacc.yy' to see how this is done.
Item_num_func
or
Item_str_func
, depending on whether your function returns a number or a
string.
double Item_func_newname::val() longlong Item_func_newname::val_int() String *Item_func_newname::Str(String *str)
void Item_func_newname::fix_length_and_dec()This function should at least calculate
max_length
based on the
given arguments. max_length
is the maximum number of characters
the function may return. This function should also set maybe_null = 0
if the main function can't return a NULL
value. The function can check
if any of the function arguments can return NULL
by checking the
arguments maybe_null
variable.
All functions must be thread-safe.
For string functions, there are some additional considerations to be aware of:
String *str
argument provides a string
buffer that may be used to hold the result.
Avec MySQL, vous pouvez définir une procédure en C++ qui pourra accéder et
modifier les données d'une requête, avant qu'elles ne soient envoyées au client.
La modification peut être faite ligne par ligne, ou bien par groupe (avec GROUP BY
).
Nous avons créé un exemple de procédure dans MySQL 3.23 pour montrer comment ca fonctionne :
analyse([max elements,[max memory]])
Cette procédure est définie dans le fichier `sql/sql_analyse.cc'. Elle examine le résultat d'une requête et retourne cette analyse.
max elements
(par défaut 256) est le nombre maximum de valeurs distinctes que la procédure
analyse
va utiliser par colonne. max elements
est utilisé par analyse
pour s'assurer que
le type optimal de la colonne devrait être ENUM
.
max memory
(par défaut 8192) est la taille maximale de mémoire que analyse
peut allouer par colonne, lorsqu'elle essaie de trouver des valeurs distinctes.
SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])
Pour le moment, la seule documentation pour cette fonction est dans le source. :( (et en anglais :( ).
Vous pouvez trouver d'autres informations concernant les procédures en examinant les fichiers suivants :
MySQL fournit l'accès à ODBC grÅce au programme MyODBC.
MyODBC est un pilote ODBC (2.50) 32-bit level 0 driver pour Windows95 et Windows NT. Nous esperons que quelqu'un voudra bien le porter sous Windows 3.x.
MyODBC a été testé avec sucess sur Access, Admndemo.exe, C++-Builder, Centura Team Developer (feu Gupta SQL/Windows), ColdFusion (sous Solaris et NT service pack 5), Crystal Reports, DataJunction, Delphi, ERwin, Excel, iHTML, FileMaker Pro, FoxPro, Notes 4.5/4.6, SBSS, Perl DBD-ODBC, Paradox, Powerbuilder, Powerdesigner 32 bit, VC++ et Visual Basic.
Si vous connaissez d'autres applications qui fonctionnent avec MyODBC, laissez nous un myodbc@lists.mysql.com !
Si vous rencontrez des difficultés, vous préférons avoir le fichier d'historique du gestionnaire ODBC ODBC (l'historique que vous obtenez en demandant l'historique de ODBCADMIN) et l'historique MyODBC . Cela nous éclairera sur vos problèmes.
Pour obtenir l'historique de MyODBC, cochez l'option 'Trace MyODBC' dans l'écran de connexion/configuration de MyODBC. L'historique sera écrit dans le fichier `C:\myodbc.log'.
Notez que vous devez utiliser MYSQL.DLL
et pas MYSQL2.DLL
pour que cette option fonctionne.
La plupart des programmes fonctionnent avec MyODBC, mais ceux de la liste suivante on été testé par nos soins, ou vérifié par quelqu'un qui l'utilise :
BLOB
comme des objets OLE OBJECTS
. Si, à la place, vous voulez avoir des colonnes de types MEMO
, il vous faut changer la colonne en TEXT
avec ALTER TABLE
.
DATE
correctement. Si vous avez un souci avec, changez les colonnes en type DATETIME
.
"Query|SQLSpecific|Pass-Through"
dans le menu Access.
VARCHAR
plutot que ENUM
, car il ne gère pas correctement ces dernières.
CONCAT()
. Par exemple :
select CONCAT(rise_time), CONCAT(set_time) from sunrise_sunset;Les valeurs retournées sous la forme de chaînes sont correctement reconnues par Excel. L'objectif de
CONCAT()
dans cet exemple est de tromper ODBC, pour lui faire croire qu'il a à faire avec une colonne de type chaîne.
Sans cela, ODBC sait que c'est une colonne de type temps et Excel ne le comprend pas.
Notez que c'est un bug d'Excel, car ce dernier converti automatiquement les chaînes en dates.
C'est bien lorsque la source est un texte, mais c'est idiot lorsque la source est une connexion ODBC.
fReg:= TRegistry.Create; fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True); fReg.WriteString('Database', 'Documents'); fReg.WriteString('Description', ' '); fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll'); fReg.WriteString('Flag', '1'); fReg.WriteString('Password', ''); fReg.WriteString('Port', ' '); fReg.WriteString('Server', 'xmark'); fReg.WriteString('User', 'winuser'); fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True); fReg.WriteString('DocumentsFab', 'MySQL'); fReg.CloseKey; fReg.Free; Memo1.Lines.Add('DATABASE NAME='); Memo1.Lines.Add('USER NAME='); Memo1.Lines.Add('ODBC DSN=DocumentsFab'); Memo1.Lines.Add('OPEN MODE=READ/WRITE'); Memo1.Lines.Add('BATCH COUNT=200'); Memo1.Lines.Add('LANGDRIVER='); Memo1.Lines.Add('MAX ROWS=-1'); Memo1.Lines.Add('SCHEMA CACHE DIR='); Memo1.Lines.Add('SCHEMA CACHE SIZE=8'); Memo1.Lines.Add('SCHEMA CACHE TIME=-1'); Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT'); Memo1.Lines.Add('SQLQRYMODE='); Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE'); Memo1.Lines.Add('ENABLE BCD=FALSE'); Memo1.Lines.Add('ROWSET SIZE=20'); Memo1.Lines.Add('BLOBS TO CACHE=64'); Memo1.Lines.Add('BLOB SIZE=32'); AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines);
Il y a trois possibilités pour spécifier le nom du serveur sous Windows95:
ip hostnamePar exemple :
194.216.84.21 my
Exemple de configuration de ``ODBC setup'':
Windows DSN name: test Description: Ceci est ma base de test MySql Database: test Server: 194.216.84.21 User: monty Password: mon_mot_de_passe Port:
Windows DSN name
peut prendre n'importe valeur qui est unique pour votre configuraiton ODBC.
Vous n'avez pas à spécifier les valeurs de Server
, User
, Password
ou Port
dans l'écran de configuraiton ODBC.
Cependant, si vous le faites, ces valeurs seront ultérieurement utilisées comme valeurs par défaut, lors de la connexion. Vous aurez aussi la possililité de changer ces valeurs lors de la connexion.
Si le numéro de port n'est pas précisé, la valeur par défaut du port est utilisée (33)
Si vous spécifiez l'option Read options from C:\my.cnf
, les groupes client
et odbc
seront lu depuis le fichier `C:\my.cnf'.
Vous pouvez y placer toutes les options de mysql_options()
.
20.4.37 mysql_options()
.
AUTO_INCREMENT
avec ODBC
Un problème classique est de lire la valeur générée lors de la dernière opération d'auto-incrément, lors qu'ne requête INSERT
. Avec ODBC, vous pouvez toujours faire ceci :
( on suppose que votre auto
est le champs AUTO_INCREMENT
):
INSERT INTO foo (auto,text) VALUES(NULL,'text'); SELECT LAST_INSERT_ID();
Ou bien, si vous allez insérer cet ID dans une autre de table, vous pouvez faire ceci :
INSERT INTO foo (auto,text) VALUES(NULL,'text'); INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text');
Pour utiliser certaines applications ODBC (au moins Delphi et Access), la requête suivante peut servir à retrouver une ligne récemment insérée :
SELECT * FROM nom_table WHERE auto IS NULL;
MySQL
avec certains programmesLes programmes proposés dans les contributions vous permettront d'identifier vos utilisateurs à partir d'une base de données MySQL mais aussi d'enregistrer l'historique dans une base de données MySQL . http://www.mysql.com/Contrib.
Vous pouvez changer le format d'historique d'Apache pour qu'il soit facilement lisible par MySQL
en ajoutant les lignes suivantes dans le fichier de configuration Apache
LogFormat \ "\"%h\",%{%Y%m%d%H%M%S}t,%>s,\"%b\",\"%{Content-Type}o\", \ \"%U\",\"%{Referer}i\",\"%{User-Agent}i\""
Avec MySQL vous pouvez maintenant faire ceci :
LOAD DATA INFILE '/local/access_log' INTO TABLE table_name FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\'
Toutes les versions de MySQL sont testées sur de nombreuses plates-formes avant d'être livrées. Cela n'assure pas qu'il n'y ait aucune erreur dans MySQL, mais si elles existent, elles sont rares et très difficiles à trouver. Si vous avez un problème, il nous sera toujours utile que vous fassiez un bilan complet de votre système, et cela vous permettra aussi de résoudre plus sûrement votre problème.
En premier lieu, il faut savoir si le problème provient de votre démon mysqld
ou de votre client. Si vous exécutez la commande mysqladmin version
, vous pourrez savoir le temps de service de votre serveur mysqld.
Si mysqld
a terminé son service inopinément, vous en trouverez la raison dans le fichier ``mysql-data-directory/'hostname'.err''.
Etant donné qu'il est très difficile de savoir pourquoi le serveur plante, commencez par vérifier si ce qui plante chez d'autres, plante aussi pour vous. Vous pouvez ainsi tester ce qui suit :
mysqld
avec mysqladmin shutdown
, puis lancez isamchk --silent --force */*.ISM
sur toutes les tables. Enfin, relancez le démon mysqld
. Ceci vous assurera que le serveur est en état de marche. Reportez vous à la section Maintenance
.
mysqld --log
pour accéder à l'historique : vous pourrez ainsi savoir si le serveur s'arrête après une requête particulière. Près de 95% des bugs interviennent après la même requête !Généralement, c'est une des dernières requête du fichier d'historique, juste avant les lignes de redémarrage de MySQL. Vous pouvez vérifier ceci avec la séquence suivante :
mysqladmin shutdown
)
isamchk -s */*.ISM
. Réparez les tables corrompues avec isamchk -r chemin-de-la-table.ISM
.
safe_mysql --log
.
mysqld
s'interromps, vous pourrez exécuter mysql < mysql-log-file
pour recherche une éventuelle requête rebelle. Vous pouvez aussi mettre le fichier d'historique dans un autre dossier que le dossier par défaut, en lancant MySQL avec les options safe_mysqld --data=path-to-backup-directory
.
fork_test.pl
et fork2_test.pl
.
--with-debug
puis recompilez. G.1 Debugguer un serveur MySQL.
--skip-locking
de mysqld
. Sur certains systèmes, le gestionnaire lockd
de verrous ne fonctionne par correctement. Cette option (--skip-locking
) force mysqld
à ne pas l'utiliser. (Cela implique que vous ne pourrez pas lancer 2 serveurs mysqld
sur les mêmes données, et que vous devrez être très prudent lors de l'utilsiation de isamchk
, mais ce peut être une option instructive.).
mysqladmin -u root processlist
lorsque mysqld
semble fonctionner, mais ne pas répondre ? Parfois, mysqld
est dans le comas, même si il ne semble pas l'être. Le problème peut provenir du fait que toutes les connexions sont prises, ou bien d'un problème interne. mysqladmin processlist
est toujours utilisable, même en cas de surcharge de connexions, et peut fournir des informations très utiles, comme le nombre de connexions et leur statut.
mysqladmin -i 5 status
dans une nouvelle console, pour avoir des statistiques en temps réel.
mysqld
à partir de gdb
(ou d'un autre debuggeur).
back
(ou backtrace dans votre debuggeur) lorsque le dump de mysqld
est généré.
BLOB ou TEXT
(et seulement des VARCHAR
) vous pouvez essayer de remplacer tous les types VARCHAR
par CHAR
avec ALTER TABLE
. Cela va forcer MySQL à utiliser des lignes à taille fixe. Les lignes à taille fixe prennent un peu plus de place, mais sont beaucoup moins sujette à dégradation. Le gestionnaire de ligne de taille variable a été utilisé à TCX (NDT : qui a concu MySQL) depuis 3 ans au moins sans aucun problème, mais, par nature, les lignes à taille variables sont plus délicates.
MySQL server has gone away
Cette section couvre aussi l'erreur Lost connection to server during query
.
La raison la plus probable qui conduit à une erreur MySQL server has gone away
est que le serveur a dépassé le délai d'attente, et qu'il a terminé la connexion. Par défaut, les connexions sont terminée après 8 heures d'inaction.
Vous pouvez vous assurez qu le serveur MySQL fonctionne toujours avec la commande mysqladmin version
et en observant le temps de vie.
Si vous avez un script en cours, vous n'avez qu'à le relancer, et le client se reconnectera automatiquement.
Dans cette situation vous pouvez obtenir les erreurs suivantes (suivant l'OS) :
Vous pouvez voir ces erreurs survenir si vous émettez une erreur trop grande, ou de taille incorrecte. Si mysqld
recoit un paquet trop grand ou hors service, il suppose alors que quelque chose n'a pas fonctionné du coté du client, et il termine la connexion. Si vous avez des requêtes de grande taille (par exemple, si vous avez des colonnes de type BLOB
), il vaut mieux augmenter la taille maximale des requête lors du démarrage de mysqld
avec l'option -O max_allowed_packet=#
option (par défaut : 1M). La mémoire supplémentaire est allouée à la volée, ce qui permet à mysqld
de n'utiliser plus de mémoire que lorsque vous émettrez une énorme requête, ou que vous vous attendrez à une énorme réponse.@node Can not connect to server, Blocked host, Gone away, Common errors
Can't connect to [local] MySQL server
Les clients MySQL peuvent se connecter à un serveur mysqld
de deux manières différentes : soit les sockets Unix, qui se connecte via un fichier système (par défaut ``/tmp/mysqld.sock''), ou par TCP/IP, qui se connecte à un numéro de port. Les sockets Unix sont beaucoup plus rapides que les sockets TCP/IP mais uniquement sur le même ordinateur. Les sockets Unix sont utilisées par défaut si vous ne spécifiez par de nom d'hôte, ou si vous vous connectez à localhost
.
L'erreur Can't connect to ...
signifie normalement qu'il n'y a pas de serveur MySQL sur le système, ou que vous utilisez un faux fichier de socket Unix ou un mauvais port TCP/IP lorsque vous vous connectez au serveur mysqld
.
Commencez par vérifier (avec ps
) qu'il y a bien un processus nommé mysqld
sur votre serveur! Si il n'y en a pas, il vaut mieux le démarrer. 4.15.2 Problèmes avec le serveur MySQL.
Si un serveur mysqld
tourne, vous pouvez vérifier le serveur avec les connexions suivantes (le numéro de port ou le nom de fichier de socket Unix peuvent différer de votre système, bien sur...) :
shell> mysqladmin version shell> mysqladmin -h `hostname` version shell> mysqladmin -h `hostname` --port=3306 version shell> mysqladmin -h 'ip for your host' version shell> mysqladmin --socket=/tmp/mysql.sock version
Notez que l'utilisation de guillemets arrière (backquotes) plutôt que des guillemets simples autour de hostname
; force l'affichage de hostname
(i.e., l'hôte courant), à utiliser ultérieurement dans la commande mysqladmin
.
Voici quelques raisons qui causent l'erreur Can't connect to local MySQL server
:
mysqld
n'est pas lancé
mysqld
utilise le package MIT-pthreads. 4.2 Systèmes d'exploitation supportés par MySQL. Cependant, MIT-pthreads ne supporte pas les sockets Unix sockets, ce qui fait que sur ces systèmes, vous devez obligatoirement spécifier un nom d'hôte explicitement, lorsque vous vous connectez à un serveur. Essayez la commande suivante, pour vérifier la connexion au serveur :
shell> mysqladmin -h `hostname` version
mysqld
(par défaut ``/tmp/mysqld.sock''). Il est aussi possible que la table de cron
supprime automatiquement la socket MySQL (e.g., une tÅche qui va supprimer les anciens fichiers dans le dossier ``/tmp'' directory). Vous pouvez aussi lancer la commande mysqladmin version
et vérifier que la socket mysqladmin
que vous tentez d'utiliser existe vraiment. La solution dans ce cas est de modifier la tÅche de la table de cron
pour qu'elle ne supprime par ``mysqld.sock'' ou encore de placer le fichier de socket ailleurs. Vous pouvez ainsi placer le fichier de socket dans un autre dossier avec la commande suivante :
shell> ./configure --with-unix-socket-path=/path/to/socket
Vous pouvez aussi lancer safe_mysqld
avec l'option --socket=/path/to/socket
et assigner une valeur à la variable d'environnement MYSQL_UNIX_PORT
avant de démarrer votre client MySQL. Puis vous lancez le serveur mysqld
avec l'option --socket=/path/to/socket
. Si vous changez le chemin de la socket sur le serveur, vous devez le notifier aux clients MySQL. Vous pouvez le faire avec la variable d'environnement MYSQL_UNIX_PORT
ou en fournissant aux clients un chemin jusqu'à la socket. Ainsi, vous pouvez tester la commande suivante :
shell> mysqladmin --socket=/path/to/socket version
mysqld
(avec le script mysql_zap
), avant de pouvoir redémarrer un nouveau serveur MySQL. Reportez vous à la section Crashing
Si vous avez le message d'erreur Can't connect to MySQL server on un_nom_d_hote
, vous pouvez essayer les solutions suivantes :
telnet your-host-name tcp-ip-port-number
et RETURN
(plusieurs fois). Si il y a un serveur MySQL sur ce port, vous allez recevoir une réponse qui comportera notamment un numéro de version (celui du serveur en fonctionnement). Si vous recevez une erreur du style : telnet: Unable to connect to remote host: Connection refused
, C'est qu'il n'y a pas de serveur sur ce port.
port
) avec la commande mysqladmin variables
.
mysqld
n'a pas été lancé avec l'option --skip-networking
.
Host '...' is blocked
Si vous recevez une erreur telle que :
Host 'hostname' is blocked because of many connection errors. Unblock with 'mysqladmin flush-hosts'
C'est que mysqld
a reçu trop de demande de connexion (max_connect_errors
) de la part de l'hôte 'hostname'
est qu'elles ont été interrompue au cours du processus. Après max_connect_errors
echecs de connexion, mysqld
supppose que quelque chose ne va pas (une attaque éventuelle d'un hacker), et bloque toutes les connexions ultérieures, jusqu'à ce que quelqu'un exécute la commande mysqladmin flush-hosts
.
Par défaut, mysqld
se bloque après 10 erreurs de connexions. Vous pouvez modifier ce paramètre avec :
shell> safe_mysqld -O max_connect_errors=10000 &
Notez que si vous recevez cette erreur de la part d'un hôte donné, il vaut mieux vérifier qu'il n'y a pas de problème de connexion TCP/IP avec cet hôte.Si les connexions TCP/IP ne fonctionnent pas, augmenter la valeur de max_connect_errors
n'y changera rien !
Out of memory
Si vous recevez une erreur telle que :
mysql: Out of memory at line 42, 'malloc.c' mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k) ERROR 2008: MySQL client ran out of memory
Cette erreur est une erreur du client mysql
. Le client manque tout simplement de mémoire pour enregistrer le résultat complet.
Pour remédier au problème, assurez vous que votre requête est correcte, et surtout, retourne t elle un nombre raisonnable de ligne ? Si c'est le cas, vous pouvez utiliser mysql --quick
, qui utilise mysql_use_result()
pour récupérer le résultat, en déplaçant la charge de travail du client vers le serveur.
Packet too large
Lorsqu'un client MySQL ou le serveur mysqld
reçoit un paquet de taille supérieure à max_allowed_packet
octets, il va générer une erreur Packet too large
et fermer la connexion.
Si vous utilisez le client mysql
, vous pouvez changer la taille du buffer en lançant le client avec l'option mysql --set-variable=max_allowed_packet=8M
.
Si vous utilisez d'autres clients qui ne vous permettent pas de changer cette taille (comme DBI
), il faut changer la taille du buffer sur le serveur. L'option a modifier est max_allowed_packet
. Par exemple, démarrer le serveur avec l'option --set-variable=max_allowed_packet=24M
.
The table is full
Cette erreur survient lorsqu'une table temporaire excède la taille de tmp_table_size
octets. Pour éviter ce problème, vous pouvez utiliser l'option -O tmp_table_size=#
de mysqld
pour accroître la taille des tables temporaires, ou bien utiliser l'option SQL SQL_BIG_TABLES
avant d'exécuter la requête. SET OPTION
.
Vous pouvez aussi démarrer le serveur avec l'option --big-tables
. Cela revient à utiliser la clause SQL_BIG_TABLES
dans toutes les requêtes.
Commands out of sync
L'erreur Commands out of sync; You can't run this command now
vient du fait que vous appelez les commandes dans le mauvais ordre, dans votre client.
Cela arrive si, par exemple, vous utilisez mysql_use_result()
puis essayez d'exécuter une nouvelle requête avant d'appeler mysql_free_result()
. Cela peut aussi arriver si vous exécutez deux requête qui retourne des données, sans employer mysql_use_result()
ou mysql_store_result()
entre ces deux commandes.
Ignoring user
Lorsque l'erreur suivante s'affiche :
Found wrong password for user: 'some_user@some_host'; Ignoring user
Cela signifie que lorsque mysqld
a été démarré, ou qu'il a recharger les tables de permissions, il a trouvé un entrée dans la table user
avec un mot de passe invalide. Par conséquent, l'entrée est purement et simplement ignorée par le système de droits.
Quelques situations et leur solution :
mysqld
avec une vieille table user
. Vous pouvez le vérifier en exécutant la commande mysqlshow mysql user
pour voir si le mot de passe contient moins de 16 caractères. Dans ce cas, corrigez le problème avec le script scripts/add_long_password
.
--old-protocol
. Modifiez l'entrée de l'utilisateur dans la table user
en lui attribuant un nouveau mot de passe, ou redémarrez le serveur avec l'option --old-protocol
.
user
sans utiliser la fonction PASSWORD()
. Utilisez le client mysql
pour modifier l'entrée de l'utilisateur dans la table user
, et attribuez lui un nouveau mot de passe. Assurez vous que vous utilisez bien la fonction PASSWORD()
:
mysql> update user set password=PASSWORD('your password') where user='XXX';
Table 'xxx' doesn't exist
L'erreur Table 'xxx' doesn't exist
ou Can't find file: 'xxx' (errno: 2)
signifie que la table demandée n'existe pas dans la bas de données courante.
N'oubliez pas que MySQL utilise des dossiers et des fichiers pour enregistrer ses bases de données et tables, et que les noms de ces derniers sont sensibles à la casse. (Sous Win32 les noms des bases de données et tables ne sont pas sensibles à la casse mais toutes les références à une table donnée dans une même requête doivent avoir la même casse ! !).
Vous pouvez lister les tables disponibles avec la requête SHOW TABLES
. Reportez vous à la section SHOW
.
Lorsqu'un disque est plein, MySQL effectue les opérations suivantes :
Pour résoudre ce problème, vous pouvez essayer ce qui suit :
mysqladmin kill
. Le thread sera terminé lors de sa prochaine tentative d'écriture. (au pire, dans une minute).
Le client mysql
est typiquement utilisé de manière interactive de la manière suivante :
shell> mysql database
Cependant, il est possible de mettre un jeu de commande dans un fichier, et d'indiquer à mysql
de lire les commandes depuis ce fichier. Pour cela, créez un fichier texte ``fichier_texte'' qui contient les commandes que vous souhaitez exécuter. Puis, lancez mysql
comme ceci :
shell> mysql database < fichier_texte
Vous pouvez aussi commencer votre fichier texte avec la commande USE nom_base_de_donnees
. Dans ce cas, il n'est pas nécessaire de spécifier le nom de la base de donnée de travail dans la ligne de commande.
shell> mysql < text_file
12.1 Présentation des différents programmes MySQL.
MySQL utilise la variable d'environnement TMPDIR
comme chemin d'accès au dossier de fichiers temporaires. Si vous n'avez pas un tel dossier, MySQL utilise par défaut celui du système, c'est à dire généralement ``/tmp'' ou ``/usr/tmp''. Si le dossier de fichier temporaire est trop petit, il vaut mieux le changer vers un autre dossier qui soit suffisamment grand, en modifiant la valeur de safe_mysqld
! Vous pouvez aussi utiliser l'option de démarrage --tmpdir
.
MySQL crée ses fichiers temporaires en tant que fichiers cachés. Cela garanti que les fichiers ne seront effacés que lorsque mysqld
sera arrêté. L'inconvénient de cette méthode est que vous ne pourrez pas repérer le fichier temporaire gigantesque qui remplit votre dossier temporaire !
Lorsque vous utilisez des tris (ORDER BY
ou GROUP BY
), MySQL utilise généralement un ou deux fichiers temporaires. L'espace disque nécessaire est :
(longueur des données triées + taille de (pointeur de base de donnée)) * nombre de ligne utilisées * 2
taille de (pointeur de base de donnée) vaut généralement 4, mais risque d'être plus grand encore, lorsqu'il faudra gérer des tables vraiment grandes.
Pour certaines requêtes SELECT
, MySQL crée aussi une table temporaire. Celles ci ne sont pas cachés, et leur noms commence par ``SQL_*''.
ALTER TABLE et OPTIMIZE TABLE
crée toutes les deux des tables temporaires, mais dans le dossier d'origine.
Si vous avez des problèmes parce que n'importe qui peut effacer le fichier de socket ``/tmp/mysql.sock'', vous pouvez, sur la plus part des versions d'UNIX, protéger le dossier ``/tmp'' en lui attribuant le sticky
bit. Connectez vous comme root
et faites ceci :
shell> chmod +s /tmp
Cela protège votre dossier ``/tmp'' et les fichiers qui sont dedans ne pourront être effacés que par leur possesseurs (root
).
Vous pouvez vérifier que le sticky
bit est en place avec ls -ld /tmp
. Si la dernière permission affichée est t
, le sticky
bit est en place.
Access denied
6.6 Fonctionnement du système de droits. Et particulièrement 6.13 Causes des erreurs "Access denied"
.
Un serveur MySQL peut être lancé par n'importe quel utilisateur. Pour modifier mysqld
et le faire fonctionner avec l'utilisateur nom_utilisateur
, vous devez faire ceci :
mysqladmin shutdown
).
nom_utilisateur
ait les droits de lecture et écriture sur ces fichiers. (Il vous faudra peut être un accès root
):
shell> chown -R user_name /path/to/mysql/datadirSi les dossiers ou fichiers dans le dossier de données de MySQL sont des liens symboliques, vous aurez aussi à suivre ces liens, et donner les droits d'accès sur les dossiers et fichiers pointés. .
chown -R
ne suivra pas les liens pour vous.
nom_utilisateur
, ou, si vous utilisez la version MySQL 3.22 ou plus récent, lancez mysqld
en tant que root
Unix et utilisez l'option --user=user_name
. mysqld
effectuera le changement d'utilisateur avant d'accepter les connexions.
mysql.server
pour démarrer mysqld
lorsque le système redémarre, vous aurez à le modifier pour que mysqld
démarrer bien en tant que nom_utilisateur
, ou lancez mysqld
avec l'option --user
option. (Aucune modification de safe_mysqld
n'est nécessaire).
A partir de ce moment, mysqld
doit fonctionner sans problèmes, avec l'utilisateur nom_utilisateur
. Cependant, une chose n'a pas changé, ce sont les permissions sur les tables. Par défaut, juste après avoir exécuter le script mysql_install_db
), l'utilisateur root
est le seul a avoir des autorisations d'accès, de création de bases. A moins que vous n'ayez modifié ces permissions, elles ont toujours cours. Cela ne va pas vous empêcher d'accéder à l'utilisateur MySQL root
lorsque vous êtes connecté en tant qu'utilisateur Unix nom_utilisateur
: pensez à spécifier l'option -u root
dans le client.
Remarquez bien que accéder à MySQL en tant que root
, avec l'option -u root
de la ligne de commande n'a rien à voir avec le fait que MySQL est lancé par le root
Unix, ou n'importe quel autre utilisateur Unix. Les conditions d'accès et les noms d'utilisateurs de MySQL sont complétement différents de ceux Unix. La seule liaison qu'il y a entre les deux est que si vous essayez de vous connecter à la base MySQL sans fournir de nom d'utilisateur, le client va tenter de se connecter en utilisant votre nom d'utilisateur Unix comme nom d'utilisateur MySQL.
Si votre système Unix n'est pas sécurisé, vous devrez au moins mettre un mot de passe pour l'utilisateur root
MySQL. Sinon, n'importe quelle personne avec un compte sur cette machine peut utiliser la commande mysql -u root nom_base_de_donnees
et faire ce qu'elle veut.
Si vous avez des problèmes avec les droits d'accès, par exemple, si vous mysql
retourne l'erreur suivante lors de la création d'une table :
ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13)
C'est que la variable d'environnement UMASK
a été incorrectement affectée lors du démarrage de mysqld
. La valeur par défaut de umask est 0660
. Vous pouvez la modifier avec :
shell> UMASK=384 # = 600 in octal shell> export UMASK shell> /path/to/safe_mysqld &
Les erreurs ERROR '...' not found (errno: 23)
, Can't open file: ... (errno: 24)
ou n'importe quelle erreur avec errno 23
ou errno 24
, signifie que vous n'avez pas alloué assez de pointeurs de fichiers pour MySQL. Vous pouvez utiliser l'utilitaire perror
pour avoir une description de la signification de l'erreur :
shell> perror 23 File table overflow shell> perror 24 Too many open files
Le problème est que mysqld
tente de garder ouvert trop de fichiers simultanément. Vous pouvez limiter le nombre de fichier ouvert simultanément, ou bien augmenter le nombre autorisé de fichier ouverts.
Pour réduire le nombre de fichiers ouverts par mysqld
, réduisez la taille du fichier de cache des tables, avec l'option -O table_cache=32
de safe_mysqld
(la valeur par défaut est de 64). Réduire la valeur de max_connections
réduira aussi le nombre de fichiers ouverts (par défaut, 90).
Pour changer le nombre maximum de pointeurs de fichiers simultané dans mysqld
, modifiez le script safe_mysqld
. Il y a une ligne du script mise en commentaire et qui vaut : -out line ulimit -n 256
. Vous pouvez supprimer le caractère de commentaire '#'
, et changer la valeur par défaut de 256 par la valeur que vous souhaitez.
ulimit permet d'augmenter le nombre de pointeur de fichiers, mais sa valeur sera limité par le système d'exploitation. Si vous donnez une valeur qui est supérieure à ce que votre système d'exploitation peut supporter, elle sera inefficace. Consultez la documentation de votre système d'exploitation pour connaître cette valeur.
Notez que si vous lancez un shell tcsh
, ulimit
ne fonctionnera pas! tcsh
affichera aussi les valeurs incorrectes si vous demandez les valeurs courantes! Dans ce cas, il vaut mieux démarrer safe_mysqld
avec sh
!
DATE
Le format d'une colonne de type DATE
est 'YYYY-MM-DD'
. Suivant la norme ANSI SQL, aucun autre format n'est toléré. Il vous faut utiliser ce format dans les expressions UPDATE
et dans les clauses WHERE (SELECT
). Par exemple:
mysql> SELECT * FROM nom_table WHERE date >= '1997-05-05';
De manière pratique, MySQL converti automatiquement une date en nombre si la date est utilisée dans un contexte numérique (et vice versa). Il est aussi capable d'utiliser une forme non conventionnelle lors des modification, ou dans les clauses WHERE
lors de comparaisons avec des colonnes de type TIMESTAMP
, DATE
ou DATETIME
. (Non conventionnelle signifie ici que des caractères non numériques peuvent être utilisé ici. Par exemple, '1998-08-15'
et '1998#08#15'
sont équivalents.) MySQL peut aussi convertir une chaîne ne contenant pas de séparateur en date, en supposant que cela puisse avoir un sens, comme '19980815'
.
La date particulière de '0000-00-00'
peut être enregistrée et lue sous la forme de '0000-00-00'.
Lorsque vous utilisez une date telle que '0000-00-00'
avec MyODBC, elle sera automatiquement converti en NULL
par MyODBC 2.50.12 et plus récent, car ODBC ne peut pas gérer ce genre de date.
Etant donné que MySQL effectue les conversions précédentes, les exemples suivant fonctionnent :
mysql> INSERT INTO nom_table (idate) VALUES (19970505); mysql> INSERT INTO nom_table (idate) VALUES ('19970505'); mysql> INSERT INTO nom_table (idate) VALUES ('97-05-05'); mysql> INSERT INTO nom_table (idate) VALUES ('1997.05.05'); mysql> INSERT INTO nom_table (idate) VALUES ('1997 05 05'); mysql> INSERT INTO nom_table (idate) VALUES ('0000-00-00'); mysql> SELECT idate FROM nom_table WHERE idate >= '1997-05-05'; mysql> SELECT idate FROM nom_table WHERE idate >= 19970505; mysql> SELECT mod(idate,100) FROM nom_table WHERE idate >= 19970505; mysql> SELECT idate FROM nom_table WHERE idate >= '19970505';
However, the following will not work:
mysql> SELECT idate FROM nom_table WHERE STRCMP(idate,'19970505')=0;
STRCMP() est une fonction de chaîne de caractère, qui va convertir idate
en chaîne et effectuer une comparaison de type chaîne. to a string. Par contre, il ne va pas convertir '19970505'
en date, et effectuer la comparaison.
Notez aussi que MySQL ne s'assure pas qu'une date est correcte ou pas. Si vous enregistrez une date incorrecte telle que '1998-2-31'
, cette date sera enregistrée. Si une date ne peut pas être converti raisonnablement, elle sera remplacée par 0
lors de l'enregistrement. Cette technique permet d'accélerer les traitement, et nous pensons que c'est à l'application de vérifier les dates, et non pas au serveur.
Si vous avez des problèmes avec SELECT NOW()
qui vous retournerai des valeurs au format GMT et non pas dans votre heure locale, c'est que vous n'avez pas mis la variable d'environnement TZ
, à la bonne valeur. Il faut l'avoir correctement paramétré avant de lancer le serveur, ou lors de son lancement, avec safe_mysqld
ou mysql.server
.
Par défaut, MySQL effectue des recherche qui sont insensibles à la casse (bien qu'il existe des caractères qui soient insensible à la casse, tel que czech
. Cela signifie que si vous analysez une colonne avec la formule nom_colonne LIKE 'a%'
, vous allez trouver toutes les lignes qui commence par A
ou a
. Si vous voulez rendre la recherche sensible à la casse, utilisez de préférence INDEX(nom_colonne, "A")=0
pour analyser un préfixe. Ou bien utilisez STRCMP(nom_colonne, "A") = 0
, si la colonne doit être exactement un "A"
.
Les opérateurs de comparaison simples (>=, >, = , < , <=
, tri et regroupement) sont basé sur la valeur de tri de chaque caractère. Les caractères avec la même valeur de tri (comme E, e et 'e) sont traités de la même façon.
Les comparaisons LIKE
sont faites avec les valeurs majuscules de chaque caractère (E == e mais E <> 'e)
Si vous voulez qu'une colonne soit toujours traitée en tenant compte de la casse, appliquez lui l'attribut BINARY
. Voir aussi la section CREATE TABLE
.
Si vous utilisez des données en Chinois, avec l'encodage big5, il est préférable de donner à toutes vos colonnes l'attribut de BINARY
. Cela fonctionnera, car le tri des caractères big5 est basé sur l'ordre ASCII.
NULL
Le concept de valeur NULL
est une source intarrissable d'erreur pour les néophytes de SQL, qui pensent souvent que NULL
est équivalent à la chaîne vide ''
. Ceci est totalement faux! Par exemple, les deux commandes suivantes sont complètement différentes :
mysql> INSERT INTO my_table (phone) VALUES (NULL); mysql> INSERT INTO my_table (phone) VALUES ("");
Les deux exemples insèrent une valeur dans la colonne phone
, mais le premier insère la valeur NULL
et le second insère la chaîne vide. La première commande peut être considéré comme ``numéro de téléphone inconnu'' et le deuxième signifiant : ``elle n'a pas de téléphone''.
En SQL, la valeur NULL
est toujours fausse lors des comparaisons avec une autre valeur, même avec elle même. Une expression qui contient NULL
retournera toujours NULL
à moins que cela ne soit indiqué dans la documentation des opérateurs et fonction mises en jeu. Toutes les colonnes suivantes retourneront NULL
:
mysql> SELECT NULL,1+NULL,CONCAT('Invisible',NULL);
Si vous voulez rechercher des colonnes qui contiennent des valeurs NULL
, vous ne pourrez pas utiliser le test =NULL
. La commande suivant retournera toujours 0 lignes, car expr = NULL
est TOUJOURS fausse, pour toute expression:
mysql> SELECT * FROM my_table WHERE phone = NULL;
Pour rechercher des valeurs NULL
, vous devez utiliser le test IS NULL
. Les exemples suivants montrent comment rechercher les valeurs NULL
dans la colonne du numéro de téléphone :
mysql> SELECT * FROM my_table WHERE phone IS NULL; mysql> SELECT * FROM my_table WHERE phone = "";
Avec MySQL, comme pour de nombreux serveurs SQL, vous ne pouvez pas indexer des colonnes qui contiennent des valeurs NULL
. Vous devez impérativement déclarer les colonnes comme NOT NULL
. Par conséquent, il ne sera pas possible d'insérer une valeur NULL
dans une colonne indexée.
Lorsque vous chargez une table avec LOAD DATA INFILE
, les colonnes vides seront remplies par ''
. Si vous voulez insérer une valeur NULL
dans une colonne, vous devrez utiliser la séquence \N
dans le fichier texte. Le mot 'NULL'
ne peut être utilisé que dans certaines circonstances. Reportez vous à la section LOAD DATA
.
Lorsque vous utiliser une clause ORDER BY
, les valeurs NULL
apparaîtront en premier. Si vous triez dans l'ordre descendant (DESC)
, NULL
seront placées en dernier. Avec les clauses GROUP BY
, toutes les valeurs NULL
sont considérées comme égales.
Pour faciliter la manipulation des valeurs NULL
, vous disposez des opérateurs IS NULL
et IS NOT NULL
et de la fonction IFNULL()
.
Pour certains types de colonnes, NULL
est géré de manière particulière. Si vous insérez NULL
dans la première colonne de type TIMESTAMP
d'une table, la date courante sera insérée. Si vous insérez NULL
dans une colonne AUTO_INCREMENT
, le numéro suivant sera inséré.
alias
Vous pouvez utiliser les alias pour faire référence à une colonne dans les clauses GROUP BY
, ORDER BY
ou HAVING
. Les alias peuvent aussi servir à donner d'autres noms à certaines colonnes
SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt > 0; SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt > 0; SELECT id AS "Customer identity" FROM table_name;
N'oubliez pas que la norme ANSI SQL ne vous autorise pas à utiliser un alias dans les clauses WHERE
. En effet, dans la clause WHERE
les valeurs des colonnes n'ont pas encore été affectée. Par exemple, la commande suivante n'est pas valide :
SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id;
La commande WHERE
est exécutée pour déterminer quelle ligne doit être inclus dans la clause GROUP BY
tandis que HAVING
sert à reconnaître les lignes du résultat qui seront utilisées.
Etant donné que MySQL ne supporte ni les sub-selects ni les effacement sur des tables multiples, vous devrez utiliser l'approche suivante pour effacer des lignes dans deux tables en même temps
WHERE
.
DELETE FROM related_table WHERE related_column IN (selected_rows)
Si le nombre total de caractères dans la requête avec related_column
dépasse 1,048,576 (la valeur par défaut de max_allowed_packet
), il vous faudra scinder la requête en plusieurs sous-requête de plus petite taille, et exécuter des DELETE
multiples. Le meilleur rendement se situe dans une fourchette de 100-1000 effacements dans related_column
à chaque fois, si related_column
est un index. Si related_column
n'est pas un index, la vitesse sera indépendante du nombre d'arguments de la clause IN
.
Si vous avez des requêtes longues et compliquées, avec de nombreuses tables, et qui ne renvoie aucune ligne, vous pouvez utiliser la méthode suivante pour trouver l'erreur dans votre requête :
EXPLAIN
est assurez vous que tout est bon. Reportez vous à la section EXPLAIN
.
WHERE
.
LIMIT 10
.
SELECT
dans la colonne qui devrait retourner des lignes, et comparez la avec la dernière table qui a été supprimé de la requête.
FLOAT
ou DOUBLE
et des nombres à virgules, vous ne pourrez pas utiliser l'opérateur =
! Ce problème est commun à la plus part des langages informatiques, car la représentation en virgule flottante n'est pas une valeur exacte.
mysql> SELECT * FROM table_name WHERE float_column=3.5; -> mysql> SELECT * FROM table_name WHERE float_column between 3.45 and 3.55;Dans la plus part des cas, changer le
FLOAT
en DOUBLE
résoudra le problème !
mysql test < query.sql
. Vous pourrez créer un fichier de teste avec mysqldump --quick database tables > query.sql
. Editez le fichier, supprimez quelques lignes (certaines sont en trop), et ajoutez votre commande à la in. Vérifier que vous avez toujours votre problème avec :
shell> mysqladmin create test2 shell> mysql test2 < query.sql
Envoyez votre test avec mysqlbug
à mysql@lists.mysql.com.
ALTER TABLE
.
Si ALTER TABLE
s'interromps avec une erreur telle que:
Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17)
Le problème est que MySQL a planté durant la dernière commande ALTER TABLE
et qu'il y a une ancienne table du nom de ``A-quelquechose'' ou ``B-quelquechose''. Dans ce cas, allez dans le dossier de données MySQL et effacez toues les fichiers dont les noms commencent par A-
ou B-
. (Ou mieux, déplacez les simplement dans un autre dossier).
ALTER TABLE fonctionne de la manière suivante :
Si quelques chose ne fonctionne par durant ce processus, MySQL tente d'annuler les modifications. Si quelque chose d'important survient, MySQL risque de laisser la vieille table ``B-xxx'' et un simple renommage peut vous rendre vos données.
Un des points forts SQL est de dissocier l'application du format de stockage. Il est toujours possible de spécifier l'ordre dans lequel vous souhaitez lire les informations.
SELECT nom_colonne1, nom_colonne2, nom_colonne3 FROM nom_table;
Retournera les colonnes dans l'ordre order nom_colonne1
, nom_colonne2
, nom_colonne3
, tandis que:
SELECT nom_colonne1, nom_colonne3, nom_colonne2 FROM nom_table;
les retournera dans l'ordre nom_colonne1
, nom_colonne3
, nom_colonne2
.
Il est préférable de ne JAMAIS lire les colonnes en fonction de leur position, surtout dans un SELECT *
, car l'ordre des colonnes ne peut jamais être garanti. Il suffit d'une modification dans la base de données pour que votre application n'ait plus de sens.
Pour changer l'ordre des colonnes, vous pouvez suivre la méthode suivante :
INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table
.
old_table
ALTER TABLE new_table RENAME old_table
Pour répliquer une base de données, le moyen courant est l'utilisation de l'historique de modification. 9.2 Historique de modification. Cela impose à la base dont les données change d'agir en tant que maître, et des autres bases seront ses clients. Pour modifier une base cliente, il suffit de lancer l'utilitaire mysql < update_log
, avec les informations d'hôte, utilisateur et mot de passe.pour accéder à la base cliente, et d'utiliser la base maître comme source.
Si vous n'avez jamais effacé quoique ce soit d'une table, vous pouvez utiliser une colonne de type TIMESTAMP
pour savoir quelle colonne a été insérée pour modifiée dans une table depuis la dernière réplication (en comparant les dates de la dernière réplication) : vous pouvez alors ne copier que les nouvelles lignes dans la table.
Il est possible de faire une modification full duplex, en utilisant l'historique de modification (pour les effacements), et les timestamps (pour le reste). Mais, dans ce cas, vous devez être capable de gérer les conflits de données, si les valeurs ont été modifiées dans les deux tables en même temps. Vous souhaiterez probablement garder la vieille version pour pouvoir choisir laquelle est la bonne.
Etant donné que la réplication se fait avec des commandes SQL, vous ne pouvez pas utiliser les fonctions suivantes dans les requêtes lorsque vous modifiez les base de données, car elle risque de ne pas retourner la même valeur que dans la base originale :
DATABASE()
GET_LOCK()
and RELEASE_LOCK()
RAND()
USER()
, SYSTEM_USER()
or SESSION_USER()
VERSION()
Toutes les fonctions de temps sont valides, car un timestamp est envoyé au miroir en cas de besoin.. LAST_INSERT_ID()
est aussi valide.
Etant donné que les tables de MySQL sont enregistrées sous la forme de fichiers, les sauvegardes sont très faciles à faire. Pour créer une sauvegarde cohérente, verrouillez les tables dont vous avez besoin avec LOCK TABLES
. LOCK TABLES
. Vous n'aurez besoin que d'un verrou de lecture, cequi permettra aux autres threads de continuer à interroger la base, tout en vous laissant le champs libre pour faire la copie des fichiers de la base. Si vous voulez faire une requête SQL pour sauver la table, utilisez donc SELECT INTO OUTFILE
.
Un autre moyen de faire des sauvegardes d'une base de données est d'utiliser l'utilitaire mysqldump
:
shell> mysqldump --tab=/path/to/some/dir --lock-tables --optVous pouvez aussi simplement faire une copie de touts les fichiers de tables (``*.frm'', ``*.ISD'' et ``*.ISM''), tant que le serveur ne fait pas de modiication.
mysqld
si il était lancé, puis relancez le avec l'option --log-update
. Vous allez obtenir des fichiers d'historique avec des noms du type ``nomDHote.n'', où n
est un nombre incrémenté à chaque fois que vous faites un mysqladmin refresh
ou mysqladmin flush-logs
, une commande FLUSH LOGS
statement, ou que vous redémarrez le serveur. Ces fichiers d'historiques fournissent les informations dont vous aurez besoin pour répliquer une base, ou la régénérer à partir de la sauvegarde faite avec mysqldump
.
Si vous devez reconstruire une base ou une table, essayer d'abord de récupérer vos tables avec isamchk -r
. Cet utilitaire fonctionne dans 99.9% des cas. Si isamchk
échoue, utilisez la procédure suivante :
mysqldump
.
shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql
ls est utilisé pour mettre les fichiers d'historiques dans le bon ordre.
Vous pouvez aussi effectuer des sauvegardes sélectives avec SELECT * INTO OUTFILE 'nom_de_fichier' FROM nom_table
et les recharger avec LOAD DATA INFILE 'nom_de_fichier' REPLACE ...
Pour éviter d'avoir des enregistrements en double, utilisez une colonne de type PRIMARY KEY
ou UNIQUE
dans la table. L'option REPLACE
forcera le remplacement des anciens enregistrements par les nouveaux, dès que l'on tentera de doubler une valeur de la clé unique.
Il existe des cas où vous aurez besoin d'avoir plusieurs serveur MySQL sur la même machine. Par exemple, si vous voulez tester une nouvelle version sans perturber le serveur de production. Ou encore, si vous voulez fournir un serveur MySQL pour différents clients.
Pour ce faire, le moyen le plus simple et de compiler le serveur avec différents ports TCP/IP et différentes sockets, pour éviter que les serveurs utilisent les mêmes sockets ou ports.
Supposons qu'il existe un serveur configuré avec le port et la socket par défaut. Alors, pour réaliser une nouvelle configuration, vous pouvez utiliser la commande suivante :
shell> ./configure --with-tcp-port=port_number \ --with-unix-socket=file_name \ --prefix=/usr/local/mysql-3.22.9
Ici, port_number
et file_name
doivent prendre des valeurs différentes des valeurs par défaut. L'should be different than the default port number and socket file pathname, et la valeur de --prefix
doit mener à une autre installation d'un MySQL.
Vous pouvez connaître la socket et le port utilisé actuellement par MySQL avec la commande suivante :
shell> mysqladmin -h hostname --port=port_number variables
Si un serveur MySQL utilisait le port que vous avez utilisé, vous allez voir s'afficher la liste des variables de configuration les plus importantes de ce serveur, y compris le nom de la socket.
Il vous faut aussi éditer le script d'initialisation de votre machine (probablement ``mysql.server'') pour démarrer et arrêter plusieurs serveurs mysqld
.
Vous n'avez pas besoin de recompiler un nouveau serveur MySQL pour changer ses port et socket. Vous pouvez les changer en les spécifiant lors du démarrage, avec l'option safe_mysqld
:
shell> /path/to/safe_mysqld --socket=file_name --port=port_number
Si vous voulez faire fonctionner le nouveau serveur MySQL avec les mêmes bases de données que l'autre, vous devrez aussi spécifier les fichiers d'historique dans safe_mysqld
avec mes options --log
et --log-update
. Sinon, les serveurs vont être en concurrence sur les mêmes fichiers d'historique .
Attention: Normalement, vous ne devriez jamais avoir deux serveurs qui modifient en même temps des données dans une base. Si votre OS ne supporte pas le verrouillage en écriture, vous allez rencontrer quelques surprises déplaisantes.
Si vous voulez utiliser un autre dossier pour les bases du second serveur, vous pouvez utiliser l'option --datadir=path
de safe_mysqld
.
Lorsque vous voulez vous connecter à un serveur MySQL qui fonctionne sur un port différent du port par défaut, vous pouvez utiliser une des méthodes suivantes :
--host 'hostname' --port=port_numer
ou [--host localhost] --socket=file_name
.
MYSQL_UNIX_PORT
et MYSQL_TCP_PORT
pour pointer sur les sockets et ports par défaut. Si vous voulez utiliser un port ou une socket spécifique, il vaut mieux les placer dans le fichier ``.login''. 12.1 Présentation des différents programmes MySQL.
The C API code is distributed with MySQL. It is included in the
mysqlclient
library and allows C programs to access a database.
Many of the clients in the MySQL source distribution are written in C. If you are looking for examples that demonstrate how to use the C API, take a look at these clients.
Most of the other client APIs (all except Java) use the mysqlclient
library to communicate with the MySQL server. This means that, for
example, you can take advantage of many of the same environment variables
that are used by other client programs, because they are referenced from the
library. See 12.1 Présentation des différents programmes MySQL, for a list of these variables.
The client has a maximum communication buffer size. The size of the buffer that is allocated initially (16K bytes) is automatically increased up to the maximum size (the default maximum is 24M). Since buffer sizes are increased only as demand warrants, simply increasing the default maximum limit does not in inself cause more resources to be used. This size check is mostly a check for erroneous requêtesand communication packets.
The communication buffer must be large enough to contain a single SQL
statement (for client-to-server traffic) and one row of returned data (for
server-to-client traffic). Each thread's communication buffer is dynamically
enlarged to handle any query or row up to the maximum limit. For example, if
you have BLOB
values that contain up to 16M of data, you must have a
communication buffer limit of at least 16M (in both server and client). The
client's default maximum is 24M, but the default maximum in the server is
1M. You can increase this by changing the value of the
max_allowed_packet
parameter when the server is started. 10.1 Optimisation des valeurs du serveur.
The MySQL server shrinks each communication buffer to
net_buffer_length
bytes after each query. For clients, the size of
the buffer associated with a connection is not decreased until the connection
is closed, at which time client memory is reclaimed.
MYSQL
MYSQL_RES
SELECT
, SHOW
, DESCRIBE
, EXPLAIN
). The
information returned from a query is called the result set in the
remainder of this section.
MYSQL_ROW
mysql_fetch_row()
.
MYSQL_FIELD
MYSQL_FIELD
structures for each field by
calling mysql_fetch_field()
repeatedly. Field values are not part of
this structure; they are contained in a MYSQL_ROW
structure.
MYSQL_FIELD_OFFSET
mysql_field_seek()
.) Offsets are field numbers
within a row, beginning at zero.
my_ulonglong
mysql_affected_rows()
,
mysql_num_rows()
and mysql_insert_id()
. This type provides a
range of 0
to 1.84e19
.
On some systems, attempting to print a value of type my_ulonglong
will not work. To print such a value, convert it to unsigned long
and use a %lu
print format. Example:
printf (Number of rows: %lu\n", (unsigned long) mysql_num_rows(result));
The MYSQL_FIELD
structure contains the members listed below:
char * name
char * table
table
value is a NULL
pointer.
char * def
mysql_list_fields()
).
enum enum_field_types type
type
value may be one of the following:
Type value | Type meaning |
FIELD_TYPE_TINY | TINYINT field
|
FIELD_TYPE_SHORT | SMALLINT field
|
FIELD_TYPE_LONG | INTEGER field
|
FIELD_TYPE_INT24 | MEDIUMINT field
|
FIELD_TYPE_LONGLONG | BIGINT field
|
FIELD_TYPE_DECIMAL | DECIMAL or NUMERIC field
|
FIELD_TYPE_FLOAT | FLOAT field
|
FIELD_TYPE_DOUBLE | DOUBLE or REAL field
|
FIELD_TYPE_TIMESTAMP | TIMESTAMP field
|
FIELD_TYPE_DATE | DATE field
|
FIELD_TYPE_TIME | TIME field
|
FIELD_TYPE_DATETIME | DATETIME field
|
FIELD_TYPE_YEAR | YEAR field
|
FIELD_TYPE_STRING | String (CHAR or VARCHAR ) field
|
FIELD_TYPE_BLOB | BLOB or TEXT field (use max_length to determine the maximum length)
|
FIELD_TYPE_SET | SET field
|
FIELD_TYPE_ENUM | ENUM field
|
FIELD_TYPE_NULL | NULL -type field
|
FIELD_TYPE_CHAR | Deprecated; use FIELD_TYPE_TINY instead
|
IS_NUM()
macro to test whether or not a field has a
numeric type. Pass the type
value to IS_NUM()
and it
will evaluate to TRUE if the field is numeric:
if (IS_NUM(field->type)) printf("Field is numeric\n");
unsigned int length
unsigned int max_length
mysql_list_fields()
, this contains the maximum length for the field.
unsigned int flags
flags
value may have zero
or more of the following bits set:
Flag value | Flag meaning |
NOT_NULL_FLAG | Field can't be NULL
|
PRI_KEY_FLAG | Field is part of a primary key |
UNIQUE_KEY_FLAG | Field is part of a unique key |
MULTIPLE_KEY_FLAG | Field is part of a non-unique key. |
UNSIGNED_FLAG | Field has the UNSIGNED attribute
|
ZEROFILL_FLAG | Field has the ZEROFILL attribute
|
BINARY_FLAG | Field has the BINARY attribute
|
AUTO_INCREMENT_FLAG | Field has the AUTO_INCREMENT attribute
|
ENUM_FLAG | Field is an ENUM (deprecated)
|
BLOB_FLAG | Field is a BLOB or TEXT (deprecated)
|
TIMESTAMP_FLAG | Field is a TIMESTAMP (deprecated)
|
BLOB_FLAG
, ENUM_FLAG
and TIMESTAMP_FLAG
flags
is deprecated because they indicate the type of a field rather than an
attribute of its type. It is preferable to test field->type
against
FIELD_TYPE_BLOB
, FIELD_TYPE_ENUM
or FIELD_TYPE_TIMESTAMP
instead.
The example below illustrates a typical use of the flags
value:
if (field->flags & NOT_NULL_FLAG) printf("Field can't be null\n");You may use the following convenience macros to determine the boolean status of the
flags
value:
IS_NOT_NULL(flags) | True if this field is defined as NOT NULL
|
IS_PRI_KEY(flags) | True if this field is a primary key |
IS_BLOB(flags) | True if this field is a BLOB or TEXT (deprecated; test field->type instead)
|
unsigned int decimals
The functions available in the C API are listed below and are described in greater detail in the next section. 20.4 Descriptions des fonctions C API.
mysql_affected_rows() |
Returns the number of rows affected by the last UPDATE , DELETE or
INSERT query.
|
mysql_close() | Closes a server connection. |
mysql_connect() |
Connects to a MySQL server. This function is deprecated; use
mysql_real_connect() instead.
|
mysql_change_user() | Change user and database on an open connection. |
mysql_create_db() |
Creates a database. This function is deprecated; use the SQL command
CREATE DATABASE instead.
|
mysql_data_seek() | Seeks to an arbitrary row in a query result set. |
mysql_debug() |
Does a DBUG_PUSH with the given string.
|
mysql_drop_db() |
Drops a database. This function is deprecated; use the SQL command
DROP DATABASE instead.
|
mysql_dump_debug_info() | Makes the server write debug information to the log. |
mysql_eof() |
Determines whether or not the last row of a result set has been read.
This function is deprecated; mysql_errno() or mysql_error()
may be used instead.
|
mysql_errno() | Returns the error number for the most recently invoked MySQL function. |
mysql_error() | Returns the error message for the most recently invoked MySQL function. |
mysql_escape_string() | Escapes special characters in a string for use in a SQL statement. |
mysql_fetch_field() | Returns the type of the next table field. |
mysql_fetch_field_direct() | Returns the type of a table field, given a field number. |
mysql_fetch_fields() | Returns an array of all field structures. |
mysql_fetch_lengths() | Returns the lengths of all columns in the current row. |
mysql_fetch_row() | Fetches the next row from the result set. |
mysql_field_seek() | Puts the column cursor on a specified column. |
mysql_field_count() | Returns the number of result columns for the most recent query. |
mysql_field_tell() |
Returns the position of the field cursor used for the last
mysql_fetch_field() .
|
mysql_free_result() | Frees memory used by a result set. |
mysql_get_client_info() | Returns client version information. |
mysql_get_host_info() | Returns a string describing the connection. |
mysql_get_proto_info() | Returns the protocol version used by the connection. |
mysql_get_server_info() | Returns the server version number. |
mysql_info() | Returns information about the most recently executed query. |
mysql_init() |
Gets or initializes a MYSQL structure.
|
mysql_insert_id() |
Returns the ID generated for an AUTO_INCREMENT column by the previous
query.
|
mysql_kill() | Kill a given thread. |
mysql_list_dbs() | Returns database names matching a simple regular expression. |
mysql_list_fields() | Returns field names matching a simple regular expression. |
mysql_list_processes() | Returns a list of the current server threads. |
mysql_list_tables() | Returns table names matching a simple regular expression. |
mysql_num_fields() | Returns the number of columns in a result set. |
mysql_num_rows() | Returns the number of rows in a result set. |
mysql_options() |
Set connect options for mysql_connect() .
|
mysql_ping() | Checks whether or not the connection to the server is working, reconnecting as necessary. |
mysql_query() | Executes a SQL query specified as a null-terminated string. |
mysql_real_connect() | Connects to a MySQL server. |
mysql_real_query() | Executes a SQL query specified as a counted string. |
mysql_reload() | Tells the server to reload the grant tables. |
mysql_row_seek() |
Seeks to a row in a result set, using value returned from
mysql_row_tell() .
|
mysql_row_tell() | Returns the row cursor position. |
mysql_select_db() | Connects to a database. |
mysql_shutdown() | Shuts down the database server. |
mysql_stat() | Returns the server status as a string. |
mysql_store_result() | Retrieves a complete result set to the client. |
mysql_thread_id() | Returns the current thread ID. |
mysql_use_result() | Initiates a row-by-row result set retrieval. |
To connect to the server, call mysql_init()
to initialize a connection
handler, then call mysql_real_connect()
with that handler (along with
other information such as the hostname, user name and password). When you
are done with the connection, call mysql_close()
to terminate it.
While a connection is active, the client may send SQL requêtesto the server
using mysql_query()
or mysql_real_query()
. The difference
between the two is that mysql_query()
expects the query to be
specified as a null-terminated string whereas mysql_real_query()
expects a counted string. If the string contains binary data (which may
include null bytes), you must use mysql_real_query()
.
For each non-SELECT
query (e.g., INSERT
, UPDATE
,
DELETE
), you can found out how many rows were affected (changed)
by calling mysql_affected_rows()
.
For SELECT
queries, you retrieve the selected rows as a result set.
(Note that some statements are SELECT
-like in that they return rows.
These include SHOW
, DESCRIBE
and EXPLAIN
. They should
be treated the same way as SELECT
statements.)
There are two ways for a client to process result sets. One way is to
retrieve the entire result set all at once by calling
mysql_store_result()
. This function acquires from the server all the
rows returned by the query and stores them in the client. The second way is
for the client to initiate a row-by-row result set retrieval by calling
mysql_use_result()
. This function initializes the retrieval, but does
not actually get any rows from the server.
In both cases, you access rows by calling mysql_fetch_row()
. With
mysql_store_result()
, mysql_fetch_row()
accesses rows that have
already been fetched from the server. With mysql_use_result()
,
mysql_fetch_row()
actually retrieves the row from the server.
Information about as the size of the data values in each row is available by
calling mysql_fetch_lengths()
.
After you are done with a result set, call mysql_free_result()
to free the memory used for it.
The two retrieval mechanisms are complementary. Client programs should
choose the approach that is most appropriate for their requirements.
In practice, clients tend to use mysql_store_result()
more
commonly.
An advantage of mysql_store_result()
is that since the rows have all
been fetched to the client, you not only can access rows sequentially, you
can move back and forth in the result set using mysql_data_seek()
or
mysql_row_seek()
to change the current row position within the result
set. You can also find out how many rows there are by calling
mysql_num_rows()
. On the other hand, the memory requirements for
mysql_store_result()
may be very high for large result sets and you
are more likely to encounter out-of-memory conditions.
An advantage of mysql_use_result()
is that the client requires less
memory for the result set since it maintains only one row at a time (and
since there is less allocation overhead, mysql_use_result()
can be
faster). Disadvantages are that you must process each row quickly to avoid
tying up the server, you don't have random access to rows within the result
set (you can only access rows sequentially), and you don't know how many rows
are in the result set until you have retrieved them all. Furthermore, you
must retrieve all the rows even if you determine in mid-retrieval that
you've found the information you were looking for.
The API makes it possible for clients to respond appropriately to
requêtes(retrieving rows only as necessary) without knowing whether or
not the query is a SELECT
. You can do this by calling
mysql_store_result()
after each mysql_query()
(or
mysql_real_query()
). If the result set call succeeds, the query
was a SELECT
and you can read the rows. If the result set call
fails, call mysql_field_count()
to determine whether or not a
result was actually to be expected. If mysql_field_count()
returns zero, the query returned no data (indicating that it was an
INSERT
, UPDATE
, DELETE
, etc.), and thus not
expected to return rows. If mysql_field_count()
is non-zero, the
query should have returned rows, but didn't. This indicates that the
query was a SELECT
that failed. See the description for
mysql_field_count()
for an example of how this can be done.
Both mysql_store_result()
and mysql_use_result()
allow you to
obtain information about the fields that make up the result set (the number
of fields, their names and types, etc.). You can access field information
sequentially within the row by calling mysql_fetch_field()
repeatedly,
or by field number within the row by calling
mysql_fetch_field_direct()
. The current field cursor position may be
changed by calling mysql_field_seek()
. Setting the field cursor
affects subsequent calls to mysql_fetch_field()
. You can also get
information for fields all at once by calling mysql_fetch_fields()
.
For detecting and reporting errors, MySQL provides access to error
information by means of the mysql_errno()
and mysql_error()
functions. These return the error code or error message for the most
recently invoked function that can succeed or fail, allowing you to determine
when an error occurred and what it was.
In the descriptions below, a parameter or return value of NULL
means
NULL
in the sense of the C programming language, not a
MySQL NULL
value.
Functions that return a value generally return a pointer or an integer.
Unless specified otherwise, functions returning a pointer return a
non-NULL
value to indicate success or a NULL
value to indicate
an error, and functions returning an integer return zero to indicate success
or non-zero to indicate an error. Note that ``non-zero'' means just that.
Unless the function description says otherwise, do not test against a value
other than zero:
if (result) /* correct */ ... error ... if (result < 0) /* incorrect */ ... error ... if (result == -1) /* incorrect */ ... error ...
When a function returns an error, the Errors subsection of the
function description lists the possible types of errors. You can
find out which of these occurred by calling mysql_errno()
.
A string representation of the error may be obtained by calling
mysql_error()
.
mysql_affected_rows()
my_ulonglong mysql_affected_rows(MYSQL *mysql)
Returns the number of rows affected (changed) by the last UPDATE
,
DELETE
or INSERT
query. May be called immediately after
mysql_query()
for UPDATE
, DELETE
or INSERT
statements. For SELECT
statements, mysql_affected_rows()
works like mysql_num_rows()
.
mysql_affected_rows()
is currently implemented as a macro.
An integer greater than zero indicates the number of rows affected or
retrieved. Zero indicates that no records matched the WHERE
clause in
the query or that no query has yet been executed. -1 indicates that the
query returned an error or that, for a SELECT
query,
mysql_affected_rows()
was called prior to calling
mysql_store_result()
.
None.
mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10"); printf("%d products updated",mysql_affected_rows(&mysql));
mysql_close()
void mysql_close(MYSQL *mysql)
Closes a previously opened connection. mysql_close()
also deallocates
the connection handle pointed to by mysql
if the handle was allocated
automatically by mysql_init()
or mysql_real_connect()
.
None.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_connect()
MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)
This function is deprecated. It is preferable to use
mysql_real_connect()
instead.
mysql_connect()
attempts to establish a connection to a MySQL
database engine running on host
. mysql_connect()
must complete
successfully before you can execute any of the other API functions, with the
exception of mysql_get_client_info()
.
The meanings of the parameters are the same as for the corresponding
parameters for mysql_real_connect()
. See the description of that
function for more information.
Same as for mysql_real_connect()
.
Same as for mysql_real_connect()
.
mysql_change_user()
my_bool mysql_change_user(MYSQL *mysql, const char *user, const char *password,
const char *db)
Changes the user and causes the database specified by db
to
become the default (current) database on the connection specified by
mysql
. In subsequent queries, this database is the default for
table references that do not include an explicit database specifier.
This function was introduced in MySQL 3.23.3
mysql_cohange_user()
fails unless the connected user can be authenticated
or if he doesn't have permission to use the database. In this case the user and
database is not changed
Zero for success. Non-zero if an error occurred.
The same that you can get from mysql_real_connect()
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
ER_UNKNOWN_COM_ERROR
ER_ACCESS_DENIED_ERROR
ER_BAD_DB_ERROR
ER_DBACCESS_DENIED_ERROR
ER_WRONG_NOM_BASE_DE_DONNEES
if (mysql_change_user(&mysql, "user", "password", "new_database")) { fprintf(stderr, "Failed to change user. Error: %s\n", mysql_error(&mysql)); }
mysql_create_db()
int mysql_create_db(MYSQL *mysql, const char *db)
Creates the database named by the db
parameter.
This function is deprecated. It is preferable to use mysql_query()
to issue a SQL CREATE DATABASE
statement instead.
Zero if the database was created successfully. Non-zero if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
if(mysql_create_db(&mysql, "my_database")) { fprintf(stderr, "Failed to create new database. Error: %s\n", mysql_error(&mysql)); }
mysql_data_seek()
void mysql_data_seek(MYSQL_RES *result, unsigned int offset)
Seeks to an arbitrary row in a query result set. This requires that the
result set structure contains the entire result of the query, so
mysql_data_seek()
may be used in conjunction only with
mysql_store_result()
, not with mysql_use_result()
.
The offset should be a value in the range from 0 to
mysql_num_rows(result)-1
.
None.
None.
mysql_debug()
void mysql_debug(char *debug)
Does a DBUG_PUSH
with the given string. mysql_debug()
uses the
Fred Fish debug library. To use this function, you must compile the client
library to support debugging.
G.1 Debugguer un serveur MySQL. G.2 Debugguer un client MySQL.
None.
None.
The call shown below causes the client library to generate a trace file in `/tmp/client.trace' on the client machine:
mysql_debug("d:t:O,/tmp/client.trace");
mysql_drop_db()
int mysql_drop_db(MYSQL *mysql, const char *db)
Drops the database named by the db
parameter.
This function is deprecated. It is preferable to use mysql_query()
to issue a SQL DROP DATABASE
statement instead.
Zero if the database was dropped successfully. Non-zero if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
if(mysql_drop_db(&mysql, "my_database")) fprintf(stderr, "Failed to drop the database: Error: %s\n", mysql_error(&mysql));
mysql_dump_debug_info()
int mysql_dump_debug_info(MYSQL *mysql)
Instructs the server to write some debug information to the log. The connected user must have the process privilege for this to work.
Zero if the command was successful. Non-zero if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_eof()
my_bool mysql_eof(MYSQL_RES *result)
This function is deprecated. mysql_errno()
or mysql_error()
may be used instead.
mysql_eof()
determines whether or not the last row of a result
set has been read.
If you acquire a result set from a successful call to
mysql_store_result()
, the client receives the entire set in one
operation. In this case, a NULL
return from mysql_fetch_row()
always means the end of the result set has been reached and it is
unnecessary to call mysql_eof()
.
On the other hand, if you use mysql_use_result()
to initiate a result
set retrieval, the rows of the set are obtained from the server one by one as
you call mysql_fetch_row()
repeatedly. Because an error may occur on
the connection during this process, a NULL
return value from
mysql_fetch_row()
does not necessarily mean the end of the result set
was reached normally. In this case, you can use mysql_eof()
to
determine what happened. mysql_eof()
returns a non-zero value if the
end of the result set was reached and zero if an error occurred.
Historically, mysql_eof()
predates the standard MySQL error
functions mysql_errno()
and mysql_error()
. Since those error
functions provide the same information, their use is preferred over
mysql_eof()
, which is now deprecated. (In fact, they provide more
information, since mysql_eof()
returns only a boolean value whereas
the error functions indicate a reason for the error when one occurs.)
Zero if an error occurred. Non-zero if the end of the result set has been reached.
None.
The following example shows how you might use mysql_eof()
:
mysql_query(&mysql,"SELECT * FROM some_table"); result = mysql_use_result(&mysql); while((row = mysql_fetch_row(result))) { // do something with data } if(!mysql_eof(result)) // mysql_fetch_row() failed due to an error { fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); }
However, you can achieve the same effect with the standard MySQL error functions:
mysql_query(&mysql,"SELECT * FROM some_table"); result = mysql_use_result(&mysql); while((row = mysql_fetch_row(result))) { // do something with data } if(mysql_errno(&mysql)) // mysql_fetch_row() failed due to an error { fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); }
mysql_errno()
unsigned int mysql_errno(MYSQL *mysql)
For the connection specified by mysql
, mysql_errno()
returns
the error code for the most recently invoked API function that can succeed
or fail. A return value of zero means that no error occurred. Client error
message numbers are listed in the MySQL `errmsg.h' header file.
Server error message numbers are listed in `mysqld_error.h'
An error code value. Zero if no error occurred.
None.
mysql_error()
char *mysql_error(MYSQL *mysql)
For the connection specified by mysql
, mysql_error()
returns
the error message for the most recently invoked API function that can succeed
or fail. An empty string (""
) is returned if no error occurred.
This means the following two tests are equivalent:
if(mysql_errno(&mysql)) { // an error occurred } if(mysql_error(&mysql)[0] != '\0') { // an error occurred }
The language of the client error messages may be changed by recompiling the MySQL client library. Currently you can choose error messages in several different languages. 9.1 Quels sont les langues supportés par MySQL?.
A character string that describes the error. An empty string if no error occurred.
None.
mysql_escape_string()
unsigned int mysql_escape_string(char *to, const char *from, unsigned int length)
Encodes the string in from
to an escaped SQL string that can be sent
to the server in a SQL statement, and places the result in to
.
Characters encoded are NUL
(ASCII 0), `\n', `\r', `\'
and `'' ( 7.1 Syntaxe des chaînes et nombres).
The string pointed to by from
must be length
bytes long (not
including the terminating null byte). You must allocate the to
buffer
to be at least length*2+1
bytes long. When
mysql_escape_string()
returns, the contents of to
will be a
null-terminated string. The return value is the length of the encoded
string, not including the terminating null character.
char query[1000],*end; end = strmov(query,"INSERT INTO test_table values("); *end++ = '\''; end += mysql_escape_string(end,"What's this",11); *end++ = '\''; *end++ = ','; *end++ = '\''; end += mysql_escape_string(end,"binary data: \0\r\n",16); *end++ = '\''; *end++ = ')'; if (mysql_real_query(&mysql,query,(unsigned int) (end - query))) { fprintf(stderr, "Failed to insert row, Error: %s\n", mysql_error(&mysql)); }
The strmov()
function used in the example is included in the
mysqlclient
library and works like strcpy()
but returns a
pointer to the terminating null of the first parameter.
The length of the value placed into to
, not including the
terminating null character.
None.
mysql_fetch_field()
MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)
Returns the definition of one column of a result set as a MYSQL_FIELD
structure. Call this function repeatedly to retrieve information about all
columns in the result set. mysql_fetch_field()
returns NULL
when no more fields are left.
mysql_fetch_field()
is reset to return information about the first
field each time you execute a new SELECT
query. The field returned by
mysql_fetch_field()
is also affected by calls to
mysql_field_seek()
.
If you've called mysql_query()
to perform a SELECT
on a table
but have not called mysql_store_result()
, MySQL returns the
default blob length (8K bytes) if you call mysql_fetch_field()
to ask
for the length of a BLOB
field. (The 8K size is chosen because
MySQL doesn't know the maximum length for the BLOB
. This
should be made configurable sometime.) Once you've retrieved the result set,
field->max_length
contains the length of the largest value for this
column in the specific query.
The MYSQL_FIELD
structure for the current column. NULL
if no columns are left.
None.
MYSQL_FIELD *field; while((field = mysql_fetch_field(result))) { printf("field name %s\n", field->name); }
mysql_fetch_fields()
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)
Returns an array of all MYSQL_FIELD
structures for a result set.
Each structure provides the field definition for one column of the result
set.
An array of MYSQL_FIELD
structures for all columns of a result set.
None.
unsigned int num_fields; unsigned int i; MYSQL_FIELD *fields; num_fields = mysql_num_fields(result); fields = mysql_fetch_fields(result); for(i = 0; i < num_fields; i++) { printf("Field %u is %s\n", i, fields[i].name); }
mysql_fetch_field_direct()
MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)
Given a field number fieldnr
for a column within a result set, returns
that column's field definition as a MYSQL_FIELD
structure. You may use
this function to retrieve the definition for an arbitrary column. The value
of fieldnr
should be in the range from 0 to
mysql_num_fields(result)-1
.
The MYSQL_FIELD
structure for the specified column.
None.
unsigned int num_fields; unsigned int i; MYSQL_FIELD *field; num_fields = mysql_num_fields(result); for(i = 0; i < num_fields; i++) { field = mysql_fetch_field_direct(result, i); printf("Field %u is %s\n", i, field->name); }
mysql_fetch_lengths()
unsigned long *mysql_fetch_lengths(MYSQL_RES *result)
Returns the lengths of the columns of the current row within a result set.
If you plan to copy field values, this length information is also useful for
optimization, because you can avoid calling strlen()
. In addition, if
the result set contains binary data, you must use this function to
determine the size of the data, because strlen()
returns incorrect
results for any field containing null characters.
The length for empty columns and for columns containing NULL
values is
zero. To see how to distinguish these two cases, see the description for
mysql_fetch_row()
.
An array of unsigned long integers representing the size of each column (not
including any terminating null characters).
NULL
if an error occurred.
mysql_fetch_lengths()
is valid only for the current row of the result
set. It returns NULL
if you call it before calling
mysql_fetch_row()
or after retrieving all rows in the result.
MYSQL_ROW row; unsigned long *lengths; unsigned int num_fields; unsigned int i; row = mysql_fetch_row(result); if (row) { num_fields = mysql_num_fields(result); lengths = mysql_fetch_lengths(result); for(i = 0; i < num_fields; i++) { printf("Column %u is %lu bytes in length.\n", i, lengths[i]); } }
mysql_fetch_row()
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
Retrieves the next row of a result set. When used after
mysql_store_result()
, mysql_fetch_row()
returns NULL
when there are no more rows to retrieve. When used after
mysql_use_result()
, mysql_fetch_row()
returns NULL
when
there are no more rows to retrieve or if an error occurred.
The number of values in the row is given by mysql_num_fields(result)
.
If row
holds the return value from a call to mysql_fetch_row()
,
pointers to the values are accessed as row[0]
to
row[mysql_num_fields(result)-1]
. NULL
values in the row are
indicated by NULL
pointers.
The lengths of the field values in the row may be obtained by calling
mysql_fetch_lengths()
. Empty fields and fields containing
NULL
both have length 0; you can distinguish these by checking
the pointer for the field value. If the pointer is NULL
, the field
is NULL
; otherwise the field is empty.
A MYSQL_ROW
structure for the next row. NULL
if
there are no more rows to retrieve or if an error occurred.
CR_SERVER_LOST
CR_UNKNOWN_ERROR
MYSQL_ROW row; unsigned int num_fields; unsigned int i; num_fields = mysql_num_fields(result); while ((row = mysql_fetch_row(result))) { unsigned long *lengths; lengths = mysql_fetch_lengths(result); for(i = 0; i < num_fields; i++) { printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL"); } printf("\n"); }
mysql_field_count()
unsigned int mysql_field_count(MYSQL *mysql)
If you are using a version of MySQL earlier than 3.22.24, you
should use unsigned int mysql_num_fields(MYSQL *mysql)
instead.
Returns the number of columns for the most recent query on the connection.
The normal use of this function is when mysql_store_result()
returned NULL
(and thus you have no result set pointer).
In this case, you can call mysql_field_count()
to
determine whether or not mysql_store_result()
should have produced a
non-empty result. This allows the client program to take proper action
without knowing whether or not the query was a SELECT
(or
SELECT
-like) statement. The example shown below illustrates how this
may be done.
An unsigned integer representing the number of fields in a result set.
None.
MYSQL_RES *result; unsigned int num_fields; unsigned int num_rows; if (mysql_query(&mysql,query_string)) { // error } else // query succeeded, process any data returned by it { result = mysql_store_result(&mysql); if (result) // there are rows { num_fields = mysql_num_fields(result); // retrieve rows, then call mysql_free_result(result) } else // mysql_store_result() returned nothing; should it have? { if(mysql_field_count(&mysql) == 0) { // query does not return data // (it was not a SELECT) num_rows = mysql_affected_rows(&mysql); } else // mysql_store_result() should have returned data { fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); } } }
An alternative is to replace the mysql_field_count(&mysql)
call with
mysql_errno(&mysql)
. In this case, you are checking directly for an
error from mysql_store_result()
rather than inferring from the value
of mysql_field_count()
whether or not the statement was a
SELECT
.
mysql_field_seek()
MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)
Sets the field cursor to the given offset. The next call to
mysql_fetch_field()
will retrieve the field definition of the column
associated with that offset.
To seek to the beginning of a row, pass an offset
value of zero.
The previous value of the field cursor.
None.
mysql_field_tell()
MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)
Returns the position of the field cursor used for the last
mysql_fetch_field()
. This value can be used as an argument to
mysql_field_seek()
.
The current offset of the field cursor.
None.
mysql_free_result()
void mysql_free_result(MYSQL_RES *result)
Frees the memory allocated for a result set by mysql_store_result()
,
mysql_use_result()
, mysql_list_dbs()
, etc. When you are done
with a result set, you must free the memory it uses by calling
mysql_free_result()
.
None.
None.
mysql_get_client_info()
char *mysql_get_client_info(void)
Returns a string that represents the client library version.
A character string that represents the MySQL client library version.
None.
mysql_get_host_info()
char *mysql_get_host_info(MYSQL *mysql)
Returns a string describing the type of connection in use, including the server host name.
A character string representing the server host name and the connection type.
None.
mysql_get_proto_info()
unsigned int mysql_get_proto_info(MYSQL *mysql)
Returns the protocol version used by current connection.
An unsigned integer representing the protocol version used by the current connection.
None.
mysql_get_server_info()
char *mysql_get_server_info(MYSQL *mysql)
Returns a string that represents the server version number.
A character string that represents the server version number.
None.
mysql_info()
char *mysql_info(MYSQL *mysql)
Retrieves a string providing information about the most recently executed
query, but only for the statements listed below. For other statements,
mysql_info()
returns NULL
. The format of the string varies
depending on the type of query, as described below. The numbers are
illustrative only; the string will contain values appropriate for the query.
INSERT INTO ... SELECT ...
Records: 100 Duplicates: 0 Warnings: 0
INSERT INTO ... VALUES (...),(...),(...)...
Records: 3 Duplicates: 0 Warnings: 0
LOAD DATA INFILE ...
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
ALTER TABLE
Records: 3 Duplicates: 0 Warnings: 0
Note that mysql_info()
returns a non-NULL
value for the
INSERT ... VALUES
statement only if multiple value lists are
specified in the statement.
A character string representing additional information about the most
recently executed query. NULL
if no information is available for the
query.
None.
mysql_init()
MYSQL *mysql_init(MYSQL *mysql)
Allocates or initializes a MYSQL
object suitable for
mysql_real_connect()
. If mysql
is a NULL
pointer, the
function allocates, initializes and returns a new object. Otherwise the
object is initialized and the address of the object is returned. If
mysql_init()
allocates a new object, it will be freed when
mysql_close()
is called to close the connection.
An initialized MYSQL*
handle. NULL
if there was
insufficient memory to allocate a new object.
In case of insufficient memory, NULL
is returned.
mysql_insert_id()
my_ulonglong mysql_insert_id(MYSQL *mysql)
Returns the ID generated for an AUTO_INCREMENT
column by the previous
query. Use this function after you have performed an INSERT
query
into a table that contains an AUTO_INCREMENT
field.
Note that mysql_insert_id()
returns 0
if the previous query
does not generate an AUTO_INCREMENT
value. If you need to save
the value for later, be sure to call mysql_insert_id()
immediately
after the query that generates the value.
Also note that the value of the SQL LAST_INSERT_ID()
function always
contains the most recently generated AUTO_INCREMENT
value, and is
not reset between requêtessince the value of that function is maintained
in the server.
The value of the AUTO_INCREMENT
field that was updated by the previous
query. Returns zero if there was no previous query on the connection or if
the query did not update an AUTO_INCREMENT
value.
None.
mysql_kill()
int mysql_kill(MYSQL *mysql, unsigned long pid)
Asks the server to kill the thread specified by pid
.
Zero for success. Non-zero if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_list_dbs()
MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)
Returns a result set consisting of database names on the server that match
the simple regular expression specified by the wild
parameter.
wild
may contain the wildcard characters `%' or `_', or may
be a NULL
pointer to match all databases. Calling
mysql_list_dbs()
is similar to executing the query SHOW
databases [LIKE wild]
.
You must free the result set with mysql_free_result()
.
A MYSQL_RES
result set for success. NULL
if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_OUT_OF_MEMORY
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_list_fields()
MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)
Returns a result set consisting of field names in the given table that match
the simple regular expression specified by the wild
parameter.
wild
may contain the wildcard characters `%' or `_', or may
be a NULL
pointer to match all fields. Calling
mysql_list_fields()
is similar to executing the query SHOW
COLUMNS FROM nom_table [LIKE wild]
.
Note that it's recommended that you use SHOW COLUMNS FROM nom_table
instead of mysql_list_fields()
.
You must free the result set with mysql_free_result()
.
A MYSQL_RES
result set for success. NULL
if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_list_processes()
MYSQL_RES *mysql_list_processes(MYSQL *mysql)
Returns a result set describing the current server threads. This is the same
kind of information as that reported by mysqladmin processlist
.
You must free the result set with mysql_free_result()
.
A MYSQL_RES
result set for success. NULL
if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_list_tables()
MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)
Returns a result set consisting of table names in the current database that
match the simple regular expression specified by the wild
parameter.
wild
may contain the wildcard characters `%' or `_', or may
be a NULL
pointer to match all tables. Calling
mysql_list_tables()
is similar to executing the query SHOW
tables [LIKE wild]
.
You must free the result set with mysql_free_result()
.
A MYSQL_RES
result set for success. NULL
if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_num_fields()
unsigned int mysql_num_fields(MYSQL_RES *result)
or
unsigned int mysql_num_fields(MYSQL *mysql)
The second form doesn't work on MySQL 3.22.24 or newer. To pass a
MYSQL*
argument, you must use
unsigned int mysql_field_count(MYSQL *mysql)
instead.
Returns the number of columns in a result set.
Note that you can get the number of columns either from a pointer to a
result set or to a connection handle. You would use the connection handle if
mysql_store_result()
returned NULL
(and thus you have no result
set pointer). In this case, you can call mysql_field_count()
to
determine whether or not mysql_store_result()
should have produced a
non-empty result. This allows the client program to take proper action
without knowing whether or not the query was a SELECT
(or
SELECT
-like) statement. The example shown below illustrates how this
may be done.
An unsigned integer representing the number of fields in a result set.
None.
MYSQL_RES *result; unsigned int num_fields; unsigned int num_rows; if (mysql_query(&mysql,query_string)) { // error } else // query succeeded, process any data returned by it { result = mysql_store_result(&mysql); if (result) // there are rows { num_fields = mysql_num_fields(result); // retrieve rows, then call mysql_free_result(result) } else // mysql_store_result() returned nothing; should it have? { if (mysql_errno(&mysql)) { fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); } else if (mysql_field_count(&mysql) == 0) { // query does not return data // (it was not a SELECT) num_rows = mysql_affected_rows(&mysql); } } }
An alternative (if you KNOW that your query should have returned a result set)
is to replace the mysql_errno(&mysql)
call with a check if
mysql_field_count(&mysql)
is = 0. This will only happen if something
went wrong.
mysql_num_rows()
my_ulonglong mysql_num_rows(MYSQL_RES *result)
Returns the number of rows in the result set.
The use of mysql_num_rows()
depends on whether you use
mysql_store_result()
or mysql_use_result()
to return the result
set. If you use mysql_store_result()
, mysql_num_rows()
may be
called immediately. If you use mysql_use_result()
,
mysql_num_rows()
will not return the correct value until all the rows
in the result set have been retrieved.
The number of rows in the result set.
None.
mysql_options()
int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)
Can be used to set extra connect options and affect behavior for a connection.
Should be called after mysql_init()
and before
mysql_connect()
or mysql_real_connect()
.
The option
argument is the option that you want to set; The arg
argument is the value for the option. If the option is an integer, then
arg
should point to the value of the integer.
Possible options values:
Option | Argument type | Function |
MYSQL_OPT_CONNECT_TIMEOUT | unsigned int * | Connect timeout in seconds. |
MYSQL_OPT_COMPRESS | Not used | Use the compressed client/server protocol. |
MYSQL_OPT_NAMED_PIPE | Not used | Use named pipes to connect to a MySQL server on NT. |
MYSQL_INIT_COMMAND | char * | Command to execute when connecting to MySQL server. Will automatically be re-executed when reconnecting. |
MYSQL_READ_DEFAULT_FILE | char * | Read options from the named option file instead of from `my.cnf'. |
MYSQL_READ_DEFAULT_GROUP | char * | Read options from the named group from `my.cnf'.or the file specified with MYSQL_READ_DEFAULT_FILE .
|
Note that the group client
is always read if you use
MYSQL_READ_DEFAULT_FILE
or MYSQL_READ_DEFAULT_GROUP
.
The specified group in the option file may contain the following options:
compress | Use the compressed client/server protocol. |
database | Connect to this database if there was no database in the connect command |
debug | Debug options |
host | Default host name |
init-command | Command to execute when connecting to MySQL server. Will automatically be re-executed when reconnecting. |
password | Default password |
pipe | Use named pipes to connect to a MySQL server on NT. |
port | Default port number |
return-found-rows | Tell mysql_info() to return found rows instead of updated rows when using UPDATE .
|
socket | Default socket number |
timeout | Connect timeout in seconds. |
user | Default user |
For more information about option files, see 4.15.4 Fichier d'options.
Zero for success. Non-zero if you used an unknown option.
MYSQL mysql; mysql_init(&mysql); mysql_options(&mysql,MYSQL_OPT_COMPRESS,0); mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc"); if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) { fprintf(stderr, "Failed to connect to database: Error: %s\n", mysql_error(&mysql)); }
The above requests the client to use the compressed client/server protocol and
read the additional options from the odbc
section in the my.cnf
file.
mysql_ping()
int mysql_ping(MYSQL *mysql)
Checks whether or not the connection to the server is working. If it has gone down, an automatic reconnection is attempted.
This function can be used by clients that remain idle for a long while, to check whether or not the server has closed the connection and reconnect if necessary.
Zero if the server is alive. Non-zero if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_UNKNOWN_ERROR
mysql_query()
int mysql_query(MYSQL *mysql, const char *query)
Executes the SQL query pointed to by the null-terminated string query
.
The query must consist of a single SQL statement. You should not add
a terminating semicolon (`;') or \g
to the statement.
mysql_query()
cannot be used for requêtesthat contain binary data; you
should use mysql_real_query()
instead. (Binary data may contain the
`\0' character, which mysql_query()
interprets as the end of the
query string.)
Zero if the query was successful. Non-zero if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_real_connect()
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host,
const char *user, const char *passwd, const char *db,
unsigned int port, const char *unix_socket,
unsigned int client_flag)
mysql_real_connect()
attempts to establish a connection to a
MySQL database engine running on host
.
mysql_real_connect()
must complete successfully before you can execute
any of the other API functions, with the exception of
mysql_get_client_info()
.
The parameters are specified as follows:
mysql
is a pointer to a MYSQL
connection structure, or
NULL
.
If mysql
is NULL
, the C API allocates memory for the
connection structure automatically and frees it when you call
mysql_close()
. The disadvantage of this approach is that you can't
retrieve an error message if the connection fails. (To get error information
from mysql_errno()
or mysql_error()
, you must provide a valid
MYSQL
pointer.)
If the first parameter is not NULL
, it should be the address of an
existing MYSQL
structure. In this case, before calling
mysql_real_connect()
you must call mysql_init()
to initialize
the MYSQL
structure. See the example below.
host
may be either a hostname or an IP address. If
host
is NULL
or the string "localhost"
, a connection to
the local host is assumed. If the OS supports sockets (Unix) or named pipes
(Win32), they are used instead of TCP/IP to connect to the server.
user
parameter contains the user's MySQL login ID. If
user
is NULL
, the current user is assumed. Under Unix, this is
the current login name. Under Windows ODBC, the current user name must be
specified explicitly.
16.4 Comment remplir les différents champs du gestionnaire ODBC.
passwd
parameter contains the password for user
. If
passwd
is NULL
, only entries in the user
table for the
user that have a blank password field will be checked for a match. This
allows the database administrator to set up the MySQL privilege
system in such a way that users get different privileges depending on whether
or not they have specified a password.
Note: Do not attempt to encrypt the password before calling
mysql_real_connect()
; password encryption is handled automatically by
the client API.
db
is the database name.
If db
is not NULL
, the connection will set the default
database to this value.
port
is not 0, the value will be used as the port number
for the TCP/IP connection. Note that the host
parameter
determines the type of the connection.
unix_socket
is not NULL
, the string specifies the
socket or named pipe that should be used. Note that the host
parameter determines the type of the connection.
client_flag
is usually 0, but can be set to a combination
of the following flags in very special circumstances:
Flag name | Flag meaning |
CLIENT_FOUND_ROWS | Return the number of found rows, not the number of affected rows |
CLIENT_NO_SCHEMA | Don't allow the
nom_base_de_donnees.nom_table.nom_colonne syntax. This is for ODBC; it causes the
parser to generate an error if you use that syntax, which is is useful for
trapping bugs in some ODBC programs.
|
CLIENT_COMPRESS | Use compression protocol |
CLIENT_ODBC | The client is an ODBC client. This changes
mysqld to be more ODBC-friendly.
|
A MYSQL*
connection handle if the connection was successful.
NULL
if the connection was unsuccessful. For a successful connection,
the return value is the same as the value of the first parameter, unless you
pass NULL
for that parameter.
CR_CONN_HOST_ERROR
CR_CONNECTION_ERROR
CR_IPSOCK_ERROR
CR_OUT_OF_MEMORY
CR_SOCKET_CREATE_ERROR
CR_UNKNOWN_HOST
CR_VERSION_ERROR
--old-protocol
option.
CR_NAMEDPIPEOPEN_ERROR;
CR_NAMEDPIPEWAIT_ERROR;
CR_NAMEDPIPESETSTATE_ERROR;
MYSQL mysql; mysql_init(&mysql); if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) { fprintf(stderr, "Failed to connect to database: Error: %s\n", mysql_error(&mysql)); }
mysql_real_query()
int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length)
Executes the SQL query pointed to by query, which should be a string
length
bytes long. The query must consist of a single SQL statement.
You should not add a terminating semicolon (`;') or \g
to the
statement.
You must use mysql_real_query()
rather than
mysql_query()
for requêtesthat contain binary data, since binary data
may contain the `\0' character. In addition, mysql_real_query()
is faster than mysql_query()
since it does not call strlen()
on
the query string.
Zero if the query was successful. Non-zero if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_reload()
int mysql_reload(MYSQL *mysql)
Asks the MySQL server to reload the grant tables. The connected user must have the reload privilege.
This function is deprecated. It is preferable to use mysql_query()
to issue a SQL FLUSH PRIVILEGES
statement instead.
Zero for success. Non-zero if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_row_seek()
MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)
Sets the row cursor to an arbitrary row in a query result set. This requires
that the result set structure contains the entire result of the query, so
mysql_row_seek()
may be used in conjunction only with
mysql_store_result()
, not with mysql_use_result()
.
The offset should be a value returned from a call to mysql_row_tell()
or to mysql_row_seek()
. This value is not simply a row number; if you
want to seek to a row within a result set using a row number, use
mysql_data_seek()
instead.
The previous value of the row cursor. This value may be passed to a
subsequent call to mysql_row_seek()
.
None.
mysql_row_tell()
MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)
Returns the current position of the row cursor for the last
mysql_fetch_row()
. This value can be used as an argument to
mysql_row_seek()
.
You should use mysql_row_tell()
only after mysql_store_result()
,
not after mysql_use_result()
.
The current offset of the row cursor.
None.
mysql_select_db()
int mysql_select_db(MYSQL *mysql, const char *db)
Causes the database specified by db
to become the default (current)
database on the connection specified by mysql
. In subsequent queries,
this database is the default for table references that do not include an
explicit database specifier.
mysql_select_db()
fails unless the connected user can be authenticated
as having permission to use the database.
Zero for success. Non-zero if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_shutdown()
int mysql_shutdown(MYSQL *mysql)
Asks the database server to shutdown. The connected user must have shutdown privileges.
Zero for success. Non-zero if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_stat()
char *mysql_stat(MYSQL *mysql)
Returns a character string containing information similar to that provided by
the mysqladmin status
command. This includes uptime in seconds and
the number of running threads, questions, reloads and open tables.
A character string describing the server status. NULL
if an
error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_store_result()
MYSQL_RES *mysql_store_result(MYSQL *mysql)
You must call
mysql_store_result()
or mysql_use_result()
for every query
which successfully retrieves data (SELECT
, SHOW
,
DESCRIBE
, EXPLAIN
).
mysql_store_result()
reads the entire result of a query to the client,
allocates a MYSQL_RES
structure, and places the result into this
structure.
An empty result set is returned if there are no rows returned. (An empty
result set differs from a NULL
return value.)
Once you have called mysql_store_result()
, you may call
mysql_num_rows()
to find out how many rows are in the result set.
You can call mysql_fetch_row()
to fetch rows from the result set,
or mysql_row_seek()
and mysql_row_tell()
to obtain or
set the current row position within the result set.
You must call mysql_free_result()
once you are done with the result
set.
A MYSQL_RES
result structure with the results. NULL
if
an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_OUT_OF_MEMORY
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_thread_id()
unsigned long mysql_thread_id(MYSQL *mysql)
Returns the thread ID of the current connection. This value can be used as
an argument to mysql_kill()
to kill the thread.
If the connection is lost and you reconnect with mysql_ping()
, the
thread ID will change. This means you should not get the thread ID and store
it for later, you should get it when you need it.
The thread ID of the current connection.
None.
mysql_use_result()
MYSQL_RES *mysql_use_result(MYSQL *mysql)
You must call mysql_store_result()
or mysql_use_result()
for
every query which successfully retrieves data (SELECT
, SHOW
,
DESCRIBE
, EXPLAIN
).
mysql_use_result()
initiates a result set retrieval but does not
actually read the result set into the client like mysql_store_result()
does. Instead, each row must be retrieved individually by making calls to
mysql_fetch_row()
. This reads the result of a query directly from the
server without storing it in a temporary table or local buffer, which is
somewhat faster and uses much less memory than mysql_store_result()
.
The client will only allocate memory for the current row and a communication
buffer that may grow up to max_allowed_packet
bytes.
On the other hand, you shouldn't use mysql_use_result()
if you are
doing a lot of processing for each row on the client side, or if the output
is sent to a screen on which the user may type a ^S
(stop scroll).
This will tie up the server and prevent other threads from updating any
tables from which the data are fetched.
When using mysql_use_result()
, you must execute
mysql_fetch_row()
until a NULL
value is returned, otherwise the
unfetched rows will be returned as part of the result set for your next
query. The C API will give the error Commands out of sync; You can't
run this command now
if you forget to do this!
You may not use mysql_data_seek()
, mysql_row_seek()
,
mysql_row_tell()
, mysql_num_rows()
or
mysql_affected_rows()
with a result returned from
mysql_use_result()
, nor may you issue other requêtesuntil the
mysql_use_result()
has finished. (However, after you have fetched all
the rows, mysql_num_rows()
will accurately return the number of rows
fetched.)
You must call mysql_free_result()
once you are done with the result
set.
A MYSQL_RES
result structure. NULL
if an error occurred.
CR_COMMANDS_OUT_OF_SYNC
CR_OUT_OF_MEMORY
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_query()
réussi, mysql_store_result()
retourne parfois NULL?
It is possible for mysql_store_result()
to return NULL
following a successful call to mysql_query()
. When this happens, it
means one of the following conditions occurred:
malloc()
failure (for example, if the result set was too
large).
INSERT
, UPDATE
or DELETE
).
You can always check whether or not the statement should have produced a
non-empty result by calling mysql_field_count()
. If
mysql_field_count()
returns zero, the result is empty and the last
query was a statement that does not return values (for example, an
INSERT
or a DELETE
). If mysql_field_count()
returns a
non-zero value, the statement should have produced a non-empty result.
See the description of the mysql_field_count()
function for an
example.
You can test for an error by calling mysql_error()
or
mysql_errno()
.
In addition to the result set returned by a query, you can also get the following information:
mysql_affected_rows()
returns the number of rows affected by the last
query when doing an INSERT
, UPDATE
or DELETE
. An
exception is that if DELETE
is used without a WHERE
clause, the
table is truncated, which is much faster! In this case,
mysql_affected_rows()
returns zero for the number of records
affected.
mysql_num_rows()
returns the number of rows in a result set. With
mysql_store_result()
, mysql_num_rows()
may be called as soon as
mysql_store_result()
returns. With mysql_use_result()
,
mysql_num_rows()
may be called only after you have fetched all the
rows with mysql_fetch_row()
.
mysql_insert_id()
returns the ID generated by the last
query that inserted a row into a table with an AUTO_INCREMENT
index.
mysql_insert_id()
.
LOAD DATA INFILE ...
, INSERT INTO
... SELECT ...
, UPDATE
) return additional info. The result is
returned by mysql_info()
. See the description for mysql_info()
for the format of the string that it returns. mysql_info()
returns a
NULL
pointer if there is no additional information.
If you insert a record in a table containing a column that has the
AUTO_INCREMENT
attribute, you can get the most recently generated
ID by calling the mysql_insert_id()
function.
You can also retrieve the ID by using the LAST_INSERT_ID()
function in
a query string that you pass to mysql_query()
.
You can check if an AUTO_INCREMENT
index is used by executing
the following code. This also checks if the query was an INSERT
with
an AUTO_INCREMENT
index:
if (mysql_error(&mysql)[0] == 0 && mysql_num_fields(result) == 0 && mysql_insert_id(&mysql) != 0) { used_id = mysql_insert_id(&mysql); }
The most recently generated ID is maintained in the server on a
per-connection basis. It will not be changed by another client. It will not
even be changed if you update another AUTO_INCREMENT
column with a
non-magic value (that is, a value that is not NULL
and not 0
).
If you want to use the ID that was generated for one table and insert it into a second table, you can use SQL statements like this:
INSERT INTO foo (auto,text) VALUES(NULL,'text'); # generate ID by inserting NULL INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text'); # use ID in second table
When linking with the C API, the following errors may occur on some systems:
gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl Undefined first referenced symbol in file floor /usr/local/lib/mysql/libmysqlclient.a(password.o) ld: fatal: Symbol referencing errors. No output written to client
If this happens on your system, you must include the math library by
adding -lm
to the end of the compile/link line.
The client is ``almost'' thread-safe. The biggest problem is that the subroutines in `net.c' that read from sockets are not interrupt-safe. This was done with the thought that you might want to have your own alarm that can break a long read to a server.
The standard client libraries are not compiled with the thread options.
To get a thread-safe client, use the -lmysys
, -lstring
and
-ldbug
libraries and net_serv.o
that the server uses.
When using a threaded client, you can make great use of the routines in
the `thr_alarm.c' file. If you are using routines from the
mysys
library, the only thing you must remember is to call
my_init()
first!
All functions except mysql_real_connect()
are currently thread-safe.
The following notes describe how to compile a thread-safe client library and
use it in a thread-safe manner. (The notes below for
mysql_real_connect()
actually apply to mysql_connect()
as well,
but since mysql_connect()
is deprecated, you should be using
mysql_real_connect()
anyway.)
To make mysql_real_connect()
thread-safe, you must recompile the client
library with this command:
shell> CPPFLAGS=-DTHREAD_SAFE_CLIENT ./configure ...
You may get some errors because of undefined symbols when linking the standard client, because the pthread libraries are not included by default.
The resulting `libmysqlclient.a' library is now thread-safe. What this
means is that client code is thread-safe as long as two threads don't query
the same connection handle returned by mysql_real_connect()
at the
same time; the client/server protocol allows only one request at a time on a
given connection. If you want to use multiple threads on the same
connection, you must have a mutex lock around your mysql_query()
and
mysql_store_result()
call combination. Once
mysql_store_result()
is ready, the lock can be released and other
threads may query the same connection. (In other words, different threads
can use different MYSQL_RES
pointers that were created with
mysql_store_result()
, as long as they use the proper locking
protocol.) If you program with POSIX threads, you can use
pthread_mutex_lock()
and pthread_mutex_unlock()
to establish
and release a mutex lock.
If you used mysql_use_result()
rather than mysql_store_result()
,
the lock would need to surround mysql_use_result()
and the calls
to mysql_fetch_row()
. However, it really is best for threaded
clients not to use mysql_use_result()
.
This section documents the Perl DBI
interface. The former interface
was called mysqlperl
. Since DBI
/DBD
now is the
recommended Perl interface, mysqlperl
is obsolete and is not
documented here.
DBI
avec DBD::mysql
DBI
is a generic interface for many databases. That means that
you can write a script that works with many different database engines
without change. You need a DataBase Driver (DBD) defined for each
database type. For MySQL, this driver is called
DBD::mysql
.
For more information on the Perl5 DBI, please visit the DBI
web
page and read the documentation:
http://www.symbolstone.org/technology/perl/DBI/index.html
For more information on Object Oriented Programming (OOP) as defined in Perl5, see the Perl OOP page:
http://language.perl.com/info/documentation.html
Installation instructions for MySQL Perl support are given in 4.10 Remarques sur l'installation Perl.
DBI
Portable DBI méthodes
connect | Establishes a connection to a database server |
disconnect | Disconnects from the database server |
prepare | Prepares a SQL statement for execution |
execute | Executes prepared statements |
do | Prepares and executes a SQL statement |
quote | Quotes string or BLOB values to be inserted
|
fetchrow_array | Fetches the next row as an array of fields. |
fetchrow_arrayref | Fetches next row as a reference array of fields |
fetchrow_hashref | Fetches next row as a reference to a hashtable |
fetchall_arrayref | Fetches all data as an array of arrays |
finish | Finishes a statement and let the system free resources |
rows | Returns the number of rows affected |
data_sources | Returns an array of databases available on localhost |
ChopBlanks | Controls whether fetchrow_* méthodes trim spaces
|
NUM_OF_PARAMS | The number of placeholders in the prepared statement |
NULLABLE | Which columns can be NULL
|
trace | Perform tracing for debugging |
MySQL-specific méthodes
insertid | The latest AUTO_INCREMENT value
|
is_blob | Which column are BLOB values
|
is_key | Which columns are keys |
is_num | Which columns are numeric |
is_pri_key | Which columns are primary keys |
is_not_null | Which columns CANNOT be NULL . See NULLABLE .
|
length | Maximum possible column sizes |
max_length | Maximum column sizes actually present in result |
NAME | Column names |
NUM_OF_FIELDS | Number of fields returned |
table | Table names in returned set |
type | All column types |
The Perl méthodes are described in more detail in the following sections. Variables used for méthode return values have these meanings:
$dbh
$sth
$rc
$rv
Portable DBI méthodes
connect($data_source, $username, $password)
connect
méthode to make a database connection to the data
source. The $data_source
value should begin with
DBI:driver_name:
.
Example uses of connect
with the DBD::mysql
driver:
$dbh = DBI->connect("DBI:mysql:$database", $user, $password); $dbh = DBI->connect("DBI:mysql:$database:$hostname", $user, $password); $dbh = DBI->connect("DBI:mysql:$database:$hostname:$port", $user, $password);If the user name and/or password are undefined,
DBI
uses the
values of the DBI_USER
and DBI_PASS
environment variables,
respectively. If you don't specify a hostname, it defaults to
'localhost'
. If you don't specify a port number, it defaults to the
default MySQL port (33).
As of Msql-Mysql-modules
version 1.2009,
the $data_source
value allows certain modifiers:
mysql_read_default_file=file_name
mysql_read_default_group=group_name
[client]
group. By specifying the mysql_read_default_group
option, the default group becomes the [group_name]
group.
mysql_compression=1
mysql_socket=/path/to/socket
DBI
script, you can take them from the user's `~/.my.cnf'
option file instead by writing your connect
call like this:
$dbh = DBI->connect("DBI:mysql:$database" . ";mysql_read_default_file=$ENV{HOME}/.my.cnf", $user, $password);This call will read options defined for the
[client]
group in the
option file. If you wanted to do the same thing, but use options specified
for the [perl]
group instead, you could use this:
$dbh = DBI->connect("DBI:mysql:$database" . ";mysql_read_default_file=$ENV{HOME}/.my.cnf" . ";mysql_read_default_group=perl", $user, $password);
disconnect
disconnect
méthode disconnects the database handle from the database.
This is typically called right before you exit from the program.
Example:
$rc = $dbh->disconnect;
prepare($statement)
($sth)
which you can use to invoke
the execute
méthode.
Typically you handle SELECT
statements (and SELECT
-like statements
such as SHOW
, DESCRIBE
and EXPLAIN
) by means of
prepare
and execute
.
Example:
$sth = $dbh->prepare($statement) or die "Can't prepare $statement: $dbh->errstr\n";
execute
execute
méthode executes a prepared statement. For
non-SELECT
statements, execute
returns the number of rows
affected. If no rows are affected, execute
returns "0E0"
,
which Perl treats as zero but regards as true. For SELECT
statements,
execute
only starts the SQL query in the database; you need to use one
of the fetch_*
méthodes described below to retrieve the data.
Example:
$rv = $sth->execute or die "can't execute the query: $sth->errstr;
do($statement)
do
méthode prepares and executes a SQL statement and returns the
number of rows affected. If no rows are affected, do
returns
"0E0"
, which Perl treats as zero but regards as true. This méthode is
generally used for non-SELECT
statements which cannot be prepared in
advance (due to driver limitations) or which do not need to executed more
than once (inserts, deletes, etc.). Example:
$rv = $dbh->do($statement) or die "Can't execute $statement: $dbh- >errstr\n";
quote($string)
quote
méthode is used to "escape" any special characters contained in
the string and to add the required outer quotation marks.
Example:
$sql = $dbh->quote($string)
fetchrow_array
while(@row = $sth->fetchrow_array) { print qw($row[0]\t$row[1]\t$row[2]\n); }
fetchrow_arrayref
while($row_ref = $sth->fetchrow_arrayref) { print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n); }
fetchrow_hashref
while($hash_ref = $sth->fetchrow_hashref) { print qw($hash_ref->{firstname}\t$hash_ref->{lastname}\t\ $hash_ref- > title}\n); }
fetchall_arrayref
my $table = $sth->fetchall_arrayref or die "$sth->errstr\n"; my($i, $j); for $i ( 0 .. $#{$table} ) { for $j ( 0 .. $#{$table->[$i]} ) { print "$table->[$i][$j]\t"; } print "\n"; }
finish
$rc = $sth->finish;
rows
SELECT
execute
statement. Example:
$rv = $sth->rows;
NULLABLE
NULL
values.
Example:
$null_possible = $sth->{NULLABLE};
NUM_OF_FIELDS
SELECT
or SHOW FIELDS
statement. You may use this for checking whether a statement returned a
result: A zero value indicates a non-SELECT
statement like
INSERT
, DELETE
or UPDATE
.
Example:
$nr_of_fields = $sth->{NUM_OF_FIELDS};
data_sources($driver_name)
'localhost'
.
Example:
@dbs = DBI->data_sources("mysql");
ChopBlanks
fetchrow_*
méthodes will chop
leading and trailing blanks from the returned values.
Example:
$sth->{'ChopBlanks'} =1;
trace($trace_level)
trace($trace_level, $trace_filename)
trace
méthode enables or disables tracing. When invoked as a
DBI
class méthode, it affects tracing for all handles. When invoked as
a database or statement handle méthode, it affects tracing for the given
handle (and any future children of the handle). Setting $trace_level
to 2 provides detailed trace information. Setting $trace_level
to 0
disables tracing. Trace output goes to the standard error output by
default. If $trace_filename
is specified, the file is opened in
append mode and output for all traced handles is written to that
file. Example:
DBI->trace(2); # trace everything DBI->trace(2,"/tmp/dbi.out"); # trace everything to /tmp/dbi.out $dth->trace(2); # trace this database handle $sth->trace(2); # trace this statement handleYou can also enable
DBI
tracing by setting the DBI_TRACE
environment variable. Setting it to a numeric value is equivalent to calling
DBI->(value)
. Setting it to a pathname is equivalent to calling
DBI->(2,value)
.
MySQL-specific méthodes
The méthodes shown below are MySQL-specific and not part of the
DBI
standard. Several of them are now deprecated:
is_blob
, is_key
, is_num
, is_pri_key
,
is_not_null
, length
, max_length
, and table
.
Where DBI
-standard alternatives exist, they are noted below.
insertid
AUTO_INCREMENT
feature of MySQL, the new
auto-incremented values will be stored here.
Example:
$new_id = $sth->{insertid};As an alternative, you can use
$dbh->{'mysql_insertid'}
.
is_blob
BLOB
.
Example:
$keys = $sth->{is_blob};
is_key
$keys = $sth->{is_key};
is_num
$nums = $sth->{is_num};
is_pri_key
$pri_keys = $sth->{is_pri_key};
is_not_null
NULL
values.
Example:
$not_nulls = $sth->{is_not_null};
is_not_null
is deprecated; it is preferable to use the
NULLABLE
attribute (described above), since that is a DBI standard.
length
max_length
length
array indicates the maximum possible sizes that each column may
be (as declared in the table description). The max_length
array
indicates the maximum sizes actually present in the result table. Example:
$lengths = $sth->{length}; $max_lengths = $sth->{max_length};
NAME
$names = $sth->{NAME};
table
$tables = $sth->{table};
type
$types = $sth->{type};
DBI
/DBD
You can use the perldoc
command to get more information about
DBI
.
perldoc DBI perldoc DBI::FAQ perldoc DBD::mysql
You can also use the pod2man
, pod2html
, etc., tools to
translate to other formats.
And of course you can find the latest DBI
information at
the DBI
web page:
http://www.symbolstone.org/technology/perl/DBI/index.html
The MySQL Contrib directory contains an Eiffel wrapper written by Michael Ravits.
You can also find this at: http://www.netpedia.net/hosting/newplayer/
There are 2 supported JDBC drivers for MySQL (the twz and mm driver). You can find a copy of these at http://www.mysql.com/Contrib. For documentation consult any JDBC documentation and the drivers own documentation for MySQL specific features.
PHP is a server-side, HTML embedded scripting language that may be used to create dynamic web pages. It contains support for accessing several databases, including MySQL. PHP may be run as a separate program, or compiled as a module for use with the Apache web server.
The distribution and documentation are available at the PHP website.
Two API's are available in the MySQL Contrib directory.
The MySQL Contrib directory contains a Python interface written by Joseph Skinner.
You can also use the Python interface to iODBC to access a MySQL server. mxODBC
TCL at binevolve. The Contrib directory contains a TCL interface that is based on msqltcl 1.50.
mSQL
Cette section a été écrite par des développeurs MySQL, et il doit être lu avec quelques reserves. Cependant, il n'y a AUCUNE erreur factuelle, autant que nous le sachions.
Pour une liste complète de toutes les limites, fonctions et types, allez à crash-me
(en anglais).
mSQL
est plus rapide dans les tÅches suivantes :
INSERT
dans des tables simples, avec quelques colonnes et clés.
CREATE TABLE
et DROP TABLE
.
SELECT
sur ce qui n'est pas un index. (l'analyse d'une table est très simple).
mSQL
(et que
la plus part des implémentation SQL) dans les cas suivants :
SELECT
complexes.
VARCHAR
.
SELECT
avec de nombreuses expressions.
SELECT
sur les grandes tables.
mSQL
, une fois la connexion établie, les autres doivent attendre que le premier ait terminé, quelque soit la requête lancée. Lorsque cette dernière est terminée, la connexion se termine, et la prochaine connexion est ouverte.
mSQL
peut devenir desespérement lent si vous changez l'ordre des tables dans
la commande SELECT
. Dans la suite de teste, il est arrivé que mSQL
soit 15000 fois plus lent que MySQL
Cela est du à mSQL
à qui manque un optimisateur de jointures. Cependant,
si vous placez les tables dans le bon ordre, si la clause WHERE
est simple
et si elle utilise des colonnes indexées, la jointure sera plutôt rapide.
11 La suite de tests de MySQL.
ORDER BY
et GROUP BY
.
DISTINCT
.
TEXT
ou BLOB
.
GROUP BY
and HAVING
.
mSQL
ne supporte pas la clause GROUP BY
.
MySQL supporte complètement la clause GROUP BY
avec la clause HAVING
et
les instructions suivantes : COUNT()
, AVG()
, MIN()
,
MAX()
, SUM()
and STD()
. COUNT(*)
est optimisé pour retourner
TRES rapidement le bon compte si SELECT
ne fait que compter dans une seule
table, sans colonne supplémentaire, ni clause WHERE
. MIN()
et MAX()
acceptent aussi des arguments chaînes.
INSERT
et UPDATE
avec calculs.
MySQL peut faire des calculs dans une commande INSERT
et UPDATE
.
Par exemple :
mysql> UPDATE SET x=x*10+y WHERE x<20;
SELECT
avec des fonctions.
MySQL dispose de nombreuses fonctions (trop nombreuses pour être listées ici : allez à 7.3 Fonctions utilisées dans les clauses SELECT
et WHERE
).
MEDIUMINT
qui ne prend que 3 octets. Si vous avez 100,000,000 enregistrements, économiser 25% de la place peut être primordial.
mSQL2
dispose de beaucoup moins de types de colonnes, et cela rend difficile la réduction de tables.
mSQL
, et nous ne nous étendrons pas sur ce point.
mSQL
, et il est aussi moins cher que mSQL
.
Quelque soit le produit que vous décidez de choisir, pensez à prendre une licence ou un support email.
(Il vous faut aquérir une licence pour inclure MySQL dans un produit que vous vendez).
mSQL
mais avec quelques fonctionnalités en plus.
mSQL
dispose d'un pilote JDBC, mais nous n'avons que très peu d'expérience, et ne pouvons pas comparer.
GROUP BY
etc...
ne sont pas implémentés dans mSQL
, il a pas mal de retard.
Pour dire les choses simplement, il suffit de comparer le fichier d'historique
de mSQL
et de le comparer à la section news de MySQL Reference Manual ( D Historique des versions de MySQL).
Le logiciel le plus rapidement developpé est une évidence.
mSQL
et MySQL dispose d'outils partenaires très interssants.
Etant donné qu'il n'est pas facile de porter ces outils de MySQL
à
mSQL), la plus part des applications interssantes, disponibles
pour mSQL
sont aussi disponibles pour MySQL.
MySQL est livré avec un utilitaire tout simple, msql2mysql
qui corrige les problèmes d'orthographe dans les API C entre mSQL
et MySQL
Par exemple, il va remplacer les appels à msqlConnect()
par
mysql_connect()
. Convertir un programme client de mSQL
à MySQL
ne prend que quelques minutes.
mSQL
pour MySQL
Selon notre expérience, il ne prendrait que quelques heures
pour convertir des outils tels que msql-tcl
et msqljava
qui utilisent
les API C mSQL
pour qu'ils fonctionnent avec MySQL.
Les instructions de conversion sont :
msql2mysql
sur les sources. Cele requiert le programme
replace
, qui est distribués par MySQL.
Les différences entre les API C mSQL
et les API C MySQL sont :
MYSQL
comme type de connexion,
(mSQL
utilise un entier int
).
mysql_connect()
prend un pointeur sur une structure MYSQL
comme paramètre.
Il est facile d'en définir un globalement, ou bien d'utiliser malloc()
pour en créer un.
mysql_connect()
prend deux paramètres pour spécifier l'utilisateur, et le mot de passe.
Vous povuez utiliser NULL, NULL
pour appeler lesv valeurs par défaut.
mysql_error()
prend une structure MYSQL
comme paramètre. Vous pouvez simplement
ajouter le paramètre de votre fonction msql_error()
si vous portez un vieux code.
mSQL
ne fait que retourner un message d'erreur.
mSQL
et MySQL diffèrent?There are enough differences that it is impossible (or at least not easy) to support both.
The most significant ways in which the MySQL protocol differs
from the mSQL
protocol are listed below:
mSQL
2.0 diffère de MySQLColumn types
MySQL
CREATE TABLE
):
ENUM
type for one of a set of strings.
SET
type for many of a set of strings.
BIGINT
type for 64-bit integers.
UNSIGNED
option for integer columns.
ZEROFILL
option for integer columns.
AUTO_INCREMENT
option for integer columns that are a
PRIMARY KEY
.
mysql_insert_id()
.
DEFAULT
value for all columns.
mSQL2
mSQL
column types correspond to the MySQL types shown below:
mSQL type | Corresponding MySQL type |
CHAR(len) | CHAR(len)
|
TEXT(len) | TEXT(len) . len is the maximal length.
And LIKE works.
|
INT | INT . With many more options!
|
REAL | REAL . Or FLOAT . Both 4- and 8-byte versions are available.
|
UINT | INT UNSIGNED
|
DATE | DATE . Uses ANSI SQL format rather than mSQL 's own.
|
TIME | TIME
|
MONEY | DECIMAL(12,2) . A fixed-point value with two decimals.
|
Index creation
MySQL
CREATE TABLE
statement.
mSQL
CREATE INDEX
statements.
To insert a unique identifier into a table
MySQL
AUTO_INCREMENT
as a column type
specifier.
mysql_insert_id()
.
mSQL
SEQUENCE
on a table and select the _seq
column.
To obtain a unique identifier for a row
MySQL
PRIMARY KEY
or UNIQUE
key to the table.
mSQL
_rowid
column. Observe that _rowid
may change over time
depending on many factors.
To get the time a column was last modified
MySQL
TIMESTAMP
column to the table. This column is automatically set
to the current date and time for INSERT
or UPDATE
statements if
you don't give the column a value or if you give it a NULL
value.
mSQL
_timestamp
column.
NULL
value comparisons
MySQL
NULL
is always NULL
.
mSQL
mSQL
, NULL = NULL
is TRUE. You
must change =NULL
to IS NULL
and <>NULL
to
IS NOT NULL
when porting old code from mSQL
to MySQL.
String comparisons
MySQL
BINARY
attribute, which causes comparisons to be done according to the
ASCII order used on the MySQL server host.
mSQL
Case-insensitive searching
MySQL
LIKE
is a case-insensitive or case-sensitive operator, depending on
the columns involved. If possible, MySQL uses indexes if the
LIKE
argument doesn't start with a wildcard character.
mSQL
CLIKE
.
Handling of trailing spaces
MySQL
CHAR
and VARCHAR
columns. Use a TEXT
column if this behavior is not desired.
mSQL
WHERE
clauses
MySQL
AND
is evaluated
before OR
). To get mSQL
behavior in MySQL, use
parentheses (as shown below).
mSQL
mSQL
query:
mysql> SELECT * FROM table WHERE a=1 AND b=2 OR a=3 AND b=4;To make MySQL evaluate this the way that
mSQL
would,
you must add parentheses:
mysql> SELECT * FROM table WHERE (a=1 AND (b=2 OR (a=3 AND (b=4))));
Access control
MySQL
mSQL
PostgreSQL
has some more advanced features like user-defined
types, triggers, rules and some transaction support. However, PostgreSQL lacks
many of the standard types and functions from ANSI SQL and ODBC. See the
crash-me
web page
for a complete list of limits and which types and functions are supported
or unsupported.
Normally, PostgreSQL
is a magnitude slower than
MySQL. 11 La suite de tests de MySQL. This is due largely to their
transactions system. If you really need transactions or the rich type
system PostgreSQL offers and you can afford the speed penalty, you
should take a look at PostgreSQL.
PHP
et MySQLSend any additions to this list to webmaster@mysql.com.
Many users of MySQL have contributed very useful support tools and addons.
A list of what is available at http://www.mysql.com/Contrib
(or any mirror) is shown below.
If you want to build MySQL support for the Perl DBI
/DBD
interface, you should fetch the Data-Dumper
, DBI
, and
Msql-Mysql-modules
files and install them.
4.10 Remarques sur l'installation Perl.
00-README This listing.
Data-Dumper
module. Useful with DBI
/DBD
support.
DBI
module.
DBD
module to access mSQL and MySQL databases..
Data-ShowTable
module. Useful with DBI
/DBD
support.
libmysql.dll
, by Blestan Tabakov,
libmysql.dll
, by bsilva@umesd.k12.or.us
guile
that allows guile
to interact with SQL
databases. By Hal Roberts.
user,
db
and
host
tables. By Tim Sailer, modified by Atif Ghaffar
DBI
1.06.
BLOB
/TEXT
columns by Daniel Koch.
mod_auth_mysql
. This is a little tool that allows you
to add/change user records storing group and/or password entries in
MySQL tables. By Harry Brueckner, brueckner@respublica.de.
mod_auth_mysql
. This is a two-part system for use with
mod_auth_mysql
.
pam
, using MySQL.
mysqldump
output to a C header file. By Harry Brueckner,
access_to_mysql.txt
, except that this
one is fully configurable, has better type conversion (including
detection of TIMESTAMP
fields), provides warnings and suggestions
while converting, quotes all special characters in text and
binary data, and so on. It will also convert to mSQL
v1 and v2,
and is free of charge for anyone. See
http://www.cynergi.net/prod/exportsql/ for latest version. By
Pedro Freire, support@cynergi.net. Note: Doesn't work with
Access2!
exportsql
. By Brian Andrews.
Note: Doesn't work with Access2!
exportsql.txt
. That is,
it imports data from MySQL into an Access database via
ODBC. This is very handy when combined with exportSQL, since it lets you
use Access for all DB design and administration, and synchronize with
your actual MySQL server either way. Free of charge. See
http://www.netdive.com/freebies/importsql/ for any updates.
Created by Laurent Bossavit of NetDIVE.
Note: Doesn't work with Access2!
mSQL
to MySQL. By alfred@sb.net
mysqldump
and pipe it to
the sqlconv.pl
script and the script will parse through the
mysqldump
output and will rearrange the fields so they can be
inserted into a new table. An example is when you want to create a new
table for a different site you are working on, but the table is just a
bit different (ie - fields in different order, etc.).
By Steve Shreeve.
radiusd
to make it support MySQL. By Wim Bonis,
hylafax
outgoing faxes in a MySQL database. By Sinisa
Milivojevic, sinisa@coresinc.com.
Les contributeurs à la distribution MySQL sont listés ci dessous, dans un ordre aléatoire :
mysqld
.
mysys
.
NISAM
et MyISAM
(fichier à index B-tree
et compression d'index, multi format de ligne).
heap
. Un système de mémoire en table, avec notre hashage supérieur. Utilisé depuis 1981, et publié en 1984.
replace
(regardez le, c'est grandiose).
mSQL
comme msqlperl
, DBD
/DBI
et DB2mysql
.
texi2html
. Mais aussi la mise à jour automatique du manuel sur le site.
libtool
.
mysys
.
mSQL
, mais nous ne l'avons pas trouvé satisfaisant pour nos objectifs,
ce qui nous a poussé à écrire notre propre interface SQL pour Unireg. mysqladmin
et mysql
ont été largement influencé par leur alter ego mSQL
.
Nous avons mis un point d'honneur à faire de la syntaxe de MySQL
un surensemble de celle de mSQL
. De nombreux concepts d'APIs ont été emprunté
à mSQL
pour rendre plus facile le portage des programmes de mSQL
à MySQL. MySQL ne contient aucun code de mSQL
.
Les deux distributions (`client/insert_test.c' et `client/select_test.c')
sont basé sur les distributions (non-copyrighté) de la distribution mSQL
mais ont été modifiés pour montrer les évolutions nécessaires entre mSQL
et MySQL.
(mSQL
est reservé par David J. Hughes.)
WHERE colonne REGEXP expression_régulière
.
gcc
), la bibliothèque libc
(dont nous avons emprunté `strto.c' pour faire fonctionner nos sources sur Linux)
et la bibliothèque readline
(pour le client mysql
).
mysqldump
(feu msqldump
, mais porté est amélioré par Monty).
DBD
_MB
et les jeu de caractères ujis et sjis .
mysqlaccess
, un programm qui montrer les droits d'accès d'un utilisateur.
xmysql
, un client X graphique de MySQL.
DBD::mysql
.
FROM_UNIXTIME()
, format d'heure, fonctions ENCRYPT()
et pour les conseils sur bison
.
Membre actif de la mailing liste.
DBI
/DBD
.
A été d'une grande aide avec crash-me
et les benchmarks. Nouvelles
fonctions de dates. Le script mysql_setpermissions.
DBI
/DBD
.
CREATE FUNCTION
et DROP FUNCTION
.
AGGREGATE
des fonctions UDF.
zlib
) du protocol client/server.
Hashage parfait pour l'analyseur lexical.
D'autres contributeurs, chercheur de bug, testeurs : James H. Thompson, Maurizio Menghini, Wojciech Tryc, Luca Berra, Zarko Mocnik, Wim Bonis, Elmar Haneke, jehamby@lightside, psmith@BayNetworks.COM, Mike Simons, Jaakko Hyv@"atti.
Et un grand nombre de retour de bug/patch des gars de la liste de diffusion.
Et un grand merci à ceux qui nous on aidé à répondre aux questions sur la liste mysql@lists.mysql.com
:
DBD-mysql
.
xmysql
et problèmes basiques d'installation.
mysqlbug
.
DBD
, Linux, et des questiosn de syntaxe SQL.
Notez bien que nous tachons de mettre à jour ce manuel en même temps que nous implémentons MySQL. Si vous trouver une version ici, qui n'est pas listée sur la page MySQL , c'est que c'est une version qui n'a pas encore été publiée.
The major difference between release 3.23 and releases 3.22 and 3.21 is that 3.23 contains a new ISAM library (MyISAM), which is more tuned for SQL than the old ISAM was.
The 3.23 release is under development, and things will be added at a fast pace to it. For the moment we recommend this version only for users that desperately need a new feature that is found only in this release (like big file support and machine-independent tables). (Note that all new functionality in MySQL 3.23 is extensively tested, but as this release involves much new code, it's difficult to test everything). This version should start to stabilise as soon as we get subselects included in it.
ASC
is now again default for ORDER BY
.
LIMIT
to UPDATE
.
mysql_change_user
.
SHOW VARIABLES
--[whitespace]
comments.
INSERT into table_name VALUES ()
'
SUBSTRING(text FROM pos)
to conform to ANSI SQL. (Before this
construct returned the rightmost 'pos' characters).
SUM(..)
with GROUP BY
returned 0 on some system.
SHOW TABLE STATUS
.
DELAY_KEY_WRITE
option to CREATE TABLE
.
AUTO_INCREMENT
on any key part.
YEAR(NOW())
and YEAR(CURDATE())
.
CASE
construct.
COALESCE()
.
SELECT * FROM table_name WHERE
key_part1 >= const AND (key_part2 = const OR key_part2 = const)
. The
bug was that some rows could be duplicated in the result.
myisamchk
without -a
updated the index
distribution wrong.
SET SQL_LOW_PRIORITY_UPDATES=1
gave parse error before.
WHERE
clause.
UPDATE nom_table SET KEY=KEY+1 WHERE KEY > 100
SELECT ... WHERE key_part1=const1 AND
key_part_2=const2 AND key_part1=const4 AND key_part2=const4
; Indextype
should be range
instead of ref
.
egcs
1.1.2 optimizer bug (when using BLOB
s) on Linux Alpha.
LOCK TABLES
combined with DELETE FROM table
.
NULL
and BLOB/TEXT
columns.
SELECT ... FROM t1 LEFT JOIN t2 ON ... WHERE t2.not_null_column IS NULL
.
ORDER BY
and GROUP BY
can be done on functions.
ORDER BY RAND()
.
WHERE key_column = function
.
WHERE key_column = column_name
even if
the columns are not identically packed.
WHERE column_name IS NULL
.
--init-file=file_name
to mysqld
.
COUNT(DISTINCT value,[value,...])
CREATE TEMPORARY TABLE
now creates a temporary table, in its own
namespace, that is automatically deleted if connection is dropped.
CASE
: CASE, THEN, WHEN, ELSE and END
.
EXPORT_SET()
and MD5()
.
MyISAM
) with a lot of new features.
10.18 Types de tables MySQL.
HEAP
tables which are extremely fast for
lookups.
LOAD_FILE(filename)
to get the contents of a file as a
string value.
<=>
which will act as =
but will return TRUE
if both arguments are NULL
. This is useful for comparing changes
between tables.
EXTRACT(interval FROM datetime)
function.
FLOAT(4)
or FLOAT(8)
are not rounded
on storage and may be in scientific notation (1.0 E+10) when retrieved.
REPLACE
is now faster than before.
LIKE
character comparison to behave as =
;
This means that 'e' LIKE 'é'
is now true.
SHOW TABLE STATUS
returns a lot of information about the tables.
LIKE
to the SHOW STATUS
command.
SHOW COLUMNS
.
packed
and comment
to SHOW INDEX
.
CREATE TABLE ... COMMENT "xxx"
).
UNIQUE
, as in
CREATE TABLE table_name (col int not null UNIQUE)
CREATE TABLE SELECT ....
CREATE TABLE IF NOT EXISTS ...
CHAR(0)
columns.
DATE_FORMAT()
now requires %
before any format character.
DELAYED
is now a reserved word (sorry about that :( ).
analyse
, file: `sql_analyse.c'.
This will describe the data in your query. Try the following:
SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])This procedure is extremely useful when you want to check the data in your table!
BINARY
cast to force a string to be compared case sensitively.
--skip-show-databases
to mysqld
.
UPDATE
now also works with
BLOB
/TEXT
columns.
INNER
join syntax. NOTE: This made INNER
an reserved word!
IP/NETMASK
syntax.
NOT NULL DATE/DATETIME
column with IS
NULL
, this is changed to a compare against 0
to satisfy some ODBC
applications. (By shreeve@uci.edu).
NULL IN (...)
now returns NULL
instead of 0
. This will
ensure that null_column NOT IN (...)
doesn't match
NULL
values.
TIME
columns.
TIME
strings to be more strict. Now the
fractional second part is detected (and currently skipped). The
following formats are supported:
[[DAYS] [H]H:]MM:]SS[.fraction]
[[[[[H]H]H]H]MM]SS[.fraction]
DATETIME
.
LOW_PRIORITY
attribute to LOAD DATA INFILE
.
LOAD DATA INFILE
.
DECIMAL(x,y)
now works according to ANSI SQL.
LAST_INSERT_ID()
is now updated for INSERT INTO ... SELECT
.
SELECT DISTINCT
is much faster; It uses the new UNIQUE
functionality in MyISAM
. One difference compared to MySQL 3.22
is that the output of DISTINCT
is not sorted anymore.
mysql_num_fields()
on
a MYSQL
object, you must use mysql_field_count()
instead.
LIBEWRAP
; Patch by Henning P . Schmiedehausen.
AUTO_INCREMENT
for other than numerical columns.
AUTO_INCREMENT
will now automatically make the column
NOT NULL
.
NULL
as the default value for AUTO_INCREMENT columns.
SQL_BIG_RESULT
; SQL_SMALL_RESULT
is now default.
--enable-large-files/--disable-large-files
switch to
configure
. See `configure.in' for some systems where this is
automatically turned off because of broken implementations.
readline
to 4.0.
CREATE TABLE
options: PACK_KEYS
and CHECKSUM
.
mysqld
option --default-table-type
.
The 3.22 version has faster and safer connect code and a lot of new nice enhancements. The reason for not including these changes in the 3.21 version is mainly that we are trying to avoid big changes to 3.21 to keep it as stable as possible. As there aren't really any MAJOR changes, upgrading to 3.22 should be very easy and painless. 4.16.2 Mise à jour de a 3.21 vers 3.22.
3.22 should also be used with the new DBD-mysql
(1.20xx) driver
that can use the new connect protocol!
BLOB/TEXT
column to REVERSE()
.
/*! */
with version numbers.
SUBSTRING(text FROM pos)
to conform to ANSI SQL. (Before this
construct returned the rightmost 'pos' characters).
LOCK TABLES
combined with DELETE FROM table
SET SQL_LOW_PRIORITY_UPDATES=#
didn't work.
GRANT ... IDENTIFIED BY
SELECT * FROM table_name WHERE key_part1 >= const AND (key_part2 = const OR key_part2 = const)
DATA
is not a reserved word anymore.
LOCK TABLES table_name READ; FLUSH TABLES;
isamchk
should now work on Win32.
libtool
1.3.2.
configure
.
--defaults-file=###
to option file handling to force use
of only one specific option file.
CREATE
syntax to ignore MySQL 3.23
keywords.
INSERT DELAYED
on a table locked with
LOCK TABLES
.
DROP TABLE
on a table that was
locked by another thread.
GRANT/REVOKE
commands in the update log.
isamchk
to detect a new error condition.
NATURAL LEFT JOIN
.
mysql_close()
directly after
mysql_init()
.
delayed_insert_thread
counting when you couldn't create a new
delayed_insert thread.
CONCAT()
with many arguments.
DELETE FROM TABLE
when table was locked by
another thread.
LEFT JOIN
involving empty tables.
mysql.db
column from char(32)
to char(60)
.
MODIFY
and DELAYED
are not reserved words anymore.
TIME
column.
Host '..' is not allowed to connect to this MySQL
server
after one had inserted a new MySQL user with a GRANT
command.
STD()
for big tables when result should be 0.
INSERT DELAYED
had some garbage at end in the update log.
mysql_install_db
(from 3.22.17).
BLOB
columns.
shutdown
all threads didn't die properly.
-O flush-time=#
to mysqld
. This is mostly
useful on Win32 and tells how often MySQL should close all
unused tables and flush all updated tables to disk.
VARCHAR
column compared with CHAR
column
didn't use keys efficiently.
--log-update
and connecting
without a default database.
configure
and portability problems.
LEFT JOIN
on tables that had circular dependencies caused
mysqld
to hang forever.
mysqladmin processlist
could kill the server if a new user logged in.
DELETE FROM nom_table WHERE key_column=nom_colonne
didn't find any matching
rows. Fixed.
DATE_ADD(column,...)
didn't work.
INSERT DELAYED
could deadlock with status 'upgrading lock'
ENCRYPT()
to take longer salt strings than 2 characters.
longlong2str
is now much faster than before. For Intel x86
platforms, this function is written in optimized assembler.
MODIFY
keyword to ALTER TABLE
.
GRANT
used with IDENTIFIED BY
didn't take effect until privileges
were flushed.
SHOW STATUS
.
ORDER BY
with 'only index' optimzation when there
were multiple key definitions for a used column.
DATE
and DATETIME
columns are now up to 5 times faster than
before.
INSERT DELAYED
can be used to let the client do other things while the
server inserts rows into a table.
LEFT JOIN USING (col1,col2)
didn't work if one used it with tables
from 2 different databases.
LOAD DATA LOCAL INFILE
didn't work in the Unix version because of
a missing file.
VARCHAR
/BLOB
on very short rows (< 4 bytes);
error 127 could occur when deleting rows.
BLOB/TEXT
through formulas didn't work for short (< 256 char)
strings.
GRANT
on a new host, mysqld
could die on the first
connect from this host.
ORDER BY
on column name that was the same
name as an alias.
BENCHMARK(loop-count,expression)
function to time expressions.
mysqld
to make it easier to start from shell
scripts.
TIMESTAMP
column to NULL
didn't record the timestamp
value in the update log.
INSERT INTO TABLE ... SELECT ... GROUP BY
.
localtime_r()
on Win32 so that it will not crash
anymore if your date is > 2039, but instead will return a time of all zero.
^Z
(ASCII 26) to \Z
as ^Z
doesn't
work with pipes on Win32.
mysql_fix_privileges
adds a new column to the mysql.func
to
support aggregate UDF functions in future MySQL releases.
NOW()
, CURDATE()
or CURTIME()
directly in a
column didn't work.
SELECT COUNT(*) ... LEFT JOIN ...
didn't work with no WHERE
part.
pthread_cond()
on the Win32 version.
get_lock()
now correctly times out on Win32!
DATE_ADD()
and DATE_SUB()
in a
WHERE
clause.
GRANT ... TO user
IDENTIFIED BY 'password'
syntax.
GRANT
checking with SELECT
on many tables.
mysql_fix_privilege_tables
to the RPM
distribution. This is not run by default since it relies on the client
package.
SQL_SMALL_RESULT
to SELECT
to force use of
fast temporary tables when you know that the result set will be small.
DATE_ADD
/DATE_SUB()
doesn't have enough days.
GRANT
compares columns in case-insensitive fashion.
ALTER TABLE
dump core in
some contexts.
user@hostname
can now include `.' and `-'
without quotes in the context of the GRANT
, REVOKE
and
SET PASSWORD FOR ...
statements.
isamchk
for tables which need big temporary files.
mysql_fix_privilege_tables
script
when you upgrade to this version! This is needed because of the new
GRANT
system. If you don't do this, you will get Access
denied
when you try to use ALTER TABLE
, CREATE INDEX
or
DROP INDEX
.
GRANT
to allow/deny users table and column access.
USER()
to return user@host
PASSWORD
for another user.
FLUSH STATUS
that sets most status variables to zero.
aborted_threads
, aborted_connects
.
connection_timeout
.
SET SQL_WARNINGS=1
to get a warning count also for simple
inserts.
SIGTERM
instead of SIGQUIT
with
shutdown to work better on FreeBSD.
\G
(print vertically) to mysql
.
SELECT HIGH_PRIORITY
... killed mysqld
.
IS NULL
on a AUTO_INCREMENT
column in a LEFT JOIN
didn't
work as expected.
MAKE_SET()
.
mysql_install_db
no longer starts the MySQL server! You
should start mysqld
with safe_mysqld
after installing it! The
MySQL RPM will however start the server as before.
--bootstrap
option to mysqld
and recoded
mysql_install_db
to use it. This will make it easier to install
MySQL with RPMs.
+
, -
(sign and minus), *
, /
, %
,
ABS()
and MOD()
to be BIGINT
aware (64-bit safe).
ALTER TABLE
that caused mysqld
to crash.
INSERT
).
INSERT INTO nom_table SET nom_colonne=value,nom_colonne=value,...
MYSQL_INIT_COMMAND
to mysql_options()
to make
a query on connect or reconnect.
MYSQL_READ_DEFAULT_FILE
and
MYSQL_READ_DEFAULT_GROUP
to mysql_options()
to read the
following parameters from the MySQL option files: port, socket,
compress, password, pipe, timeout, user, init-command, host and
database.
maybe_null
to the UDF structure.
IGNORE
to INSERT
statemants with many rows.
isamchk -rq
on each table that has an index on
a CHAR
or VARCHAR
column.
mysql_setpermission
, by Luuk de Boer, allows one
to easily create new users with permissions for specific databases.
LOAD DATA INFILE
).
SHOW STATUS
and changed format of output to
be like SHOW VARIABLES
.
extended-status
command to mysqladmin
which will show the
new status variables.
SET SQL_LOG_UPDATE=0
caused a lockup of the server.
FLUSH [ TABLES | HOSTS | LOGS | PRIVILEGES ] [, ...]
KILL
thread_id
ALTER TABLE
from a INT
to a short CHAR()
column.
SELECT HIGH_PRIORITY
; This will get a lock for the
SELECT
even if there is a thread waiting for another
SELECT
to get a WRITE LOCK
.
LIKE
on
BLOB
/TEXT
columns with \0
.
ESCAPE
option to LIKE
.
mysqladmin debug
.
mysqld
on Win32 with the --flush
option.
This will flush all tables to disk after each update. This makes things
much safer on NT/Win98 but also MUCH slower.
my_strcoll()
! The patch should always be safe to install (for any system),
but as this patch changes ISAM internals it's not yet in the default
distribution.
DATE_ADD()
and DATE_SUB()
didn't work with group functions.
mysql
will now also try to reconnect on USE DATABASE
commands.
ORDER BY
and LEFT JOIN
and const
tables.
ORDER BY
if the first ORDER BY
column
was a key and the rest of the ORDER BY
columns wasn't part of the key.
OPTIMIZE TABLE
.
DROP TABLE
and mysqladmin shutdown
on Win32
(a fatal bug from 3.22.6).
TIME columns
and negative strings.
LIMIT
clause for the DELETE
statement.
/*! ... */
syntax to hide MySQL-specific
keywords when you write portable code. MySQL will parse the code
inside the comments as if the surrounding /*!
and */
comment
characters didn't exist.
OPTIMIZE TABLE nom_table
can now be used to reclaim disk space
after many deletes. Currently, this uses ALTER TABLE
to re-generate
the table, but in the future it will use an integrated isamchk
for more speed.
libtool
to get the configure more portable.
UPDATE
and DELETE
operations when using
DATETIME
or DATE
keys.
mysqladmin proc
to display information about your own
threads. Only users with the Process_priv privilege can get
information about all threads.
YYMMDD
, YYYYMMDD
,
YYMMDDHHMMSS
for numbers when using DATETIME
and
TIMESTAMP
types. (Formerly these formats only worked with strings.)
CLIENT_IGNORE_SPACE
to allow use of spaces
after function names and before `(' (Powerbuilder requires this).
This will make all function names reserved words.
--log-long-format
option to mysqld
to enable timestamps
and INSERT_ID's in the update log.
--where
option to mysqldump
(patch by Jim Faucette).
mysqldump
.
LOAD DATA INFILE
statement, you can now use the new LOCAL
keyword to read the file from the client. mysqlimport
will
automatically use LOCAL
when importing with the TCP/IP protocol.
DROP TABLE
, ALTER TABLE
, DELETE FROM
TABLE
and mysqladmin flush-tables
under heavy usage.
Changed locking code to get better handling of locks of different types.
DBI
to 1.00 and DBD
to 1.2.0.
mysqld
. (To avoid errors if you accidentally
try to use an old error message file.)
affected_rows()
,
insert_id()
,...) are now of type BIGINT
to allow 64-bit values
to be used.
This required a minor change in the MySQL protocol which should affect
only old clients when using tables with AUTO_INCREMENT
values > 24M.
mysql_fetch_lengths()
has changed from uint *
to ulong *
. This may give a warning for old clients but should work
on most machines.
mysys
and dbug
libraries to allocate all thread variables
in one struct. This makes it easier to make a threaded `libmysql.dll'
library.
gethostname()
(instead of uname()
) when
constructing `.pid' file names.
COUNT()
, STD()
and AVG()
are extended to handle more than
4G rows.
-838:59:59
<= x <=
838:59:59
in a TIME
column.
TIME
column to too short a value, MySQL now
assumes the value is given as: [[[D ]HH:]MM:]SS
instead of
HH[:MM[:SS]]
.
TIME_TO_SEC()
and SEC_TO_TIME()
can now handle negative times
and hours up to 32767.
SET OPTION SQL_LOG_UPDATE={0|1}
to allow users with
the process privilege to bypass the update log.
(Modified patch from Sergey A Mukhin violet@rosnet.net.)
LPAD()
.
BLOB
reading from
pipes safer.
-O max_connect_errors=#
option to mysqld
.
Connect errors are now reset for each correct connection.
max_allowed_packet
to 1M
in
mysqld
.
--low-priority-updates
option to mysqld
, to give
UPDATE
operations lower priority than retrievals. You can now use
{INSERT | REPLACE | UPDATE | DELETE} LOW_PRIORITY ...
You can also use SET OPTION LOW_PRIORITY_UPDATES={0|1}
to change the
priority for one thread.
One side effect is that LOW_PRIORITY
is now a reserved word. :(
INSERT INTO table ... VALUES(...),(...),(...)
,
to allow inserting multiple rows with a single statement.
INSERT INTO nom_table
is now also cached when used with LOCK TABLES
.
(Previously only INSERT ... SELECT
and LOAD DATA INFILE
were
cached.)
GROUP BY
functions with HAVING
:
mysql> SELECT col FROM table GROUP BY col HAVING COUNT(*)>0;
mysqld
will now ignore trailing `;' characters in queries. This
is to make it easier to migrate from some other SQL servers that require the
trailing `;'.
SELECT INTO OUTFILE
.
GREATEST()
and LEAST()
functions. You must now use
these instead of the MAX()
and MIN()
functions to get the
largest/smallest value from a list of values. These can now handle REAL
,
BIGINT
and string (CHAR
or VARCHAR
) values.
DAYOFWEEK()
had offset 0 for Sunday. Changed the offset to 1.
GROUP BY
columns and fields when
there is no GROUP BY
specification.
--vertical
option to mysql
, for printing results in
vertical mode.
--tmpdir
option to mysqld
, for specifying the location
of the temporary file directory.
SELECT ... FROM table WHERE auto_increment_column IS NULLto:
SELECT ... FROM table WHERE auto_increment_column == LAST_INSERT_ID()This allows some ODBC programs (Delphi, Access) to retrieve the newly inserted row to fetch the
AUTO_INCREMENT
id.
DROP TABLE
now waits for all users to free a table before deleting it.
BIN()
, HEX()
and CONV()
for converting
between different number bases.
SUBSTRING()
with 2 arguments.
ORDER BY
and
GROUP BY
.
mysqld
now automatically disables system locking on Linux and Win32,
and for systems that use MIT-pthreads. You can force the use of locking
with the --enable-locking
option.
--console
option to mysqld
, to force a console window
(for error messages) when using Win32.
DATE_ADD()
and DATE_SUB()
functions.
mysql_ping()
to the client library.
--compress
option to all MySQL clients.
byte
to char
in `mysql.h' and `mysql_com.h'.
<<
, >>
, RPAD()
and LPAD()
.
ORDER BY
to work when no records are found
when using fields that are not in GROUP BY
(MySQL extension).
--chroot
option to mysqld
, to start mysqld
in
a chroot environment (by Nikki Chumakov nikkic@cityline.ru).
--one-thread
option to mysqld
, for debugging with
LinuxThreads (or glibc
). (This replaces the -T32
flag)
DROP TABLE IF EXISTS
to prevent an error from occurring if the
table doesn't exist.
IF
and EXISTS
are now reserved words (they would have to
be sooner or later).
mysqldump
.
mysql_ping()
.
mysql_init()
and mysql_options()
.
You now MUST call mysql_init()
before you call
mysql_real_connect()
.
You don't have to call mysql_init()
if you only use
mysql_connect()
.
mysql_options(...,MYSQL_OPT_CONNECT_TIMEOUT,...)
so you can set a
timeout for connecting to a server.
--timeout
option to mysqladmin
, as a test of
mysql_options()
.
AFTER column
and FIRST
options to
ALTER TABLE ... ADD columns
.
This makes it possible to add a new column at some specific location
within a row in an existing table.
WEEK()
now takes an optional argument to allow handling of weeks when
the week starts on Monday (some European countries). By default,
WEEK()
assumes the week starts on Sunday.
TIME
columns weren't stored properly (bug in MySQL 3.22.0).
UPDATE
now returns information about how many rows were
matched and updated, and how many ``warnings'' occurred when doing the update.
FORMAT(-100,2)
.
ENUM
and SET
columns were compared in binary (case-sensitive)
fashion; changed to be case insensitive.
mysql_real_connect()
call is changed to:
mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, uint port, const char *unix_socket, uint client_flag)
accept()
thread. This fixes permanently the telnet bug
that was a topic on the mail list some time ago.
mysqld
now has a local hostname
resolver cache so connections should actually be faster than before,
even with this feature.
nom_table@nom_base_de_donnees
or nom_base_de_donnees.nom_table
. This makes it possible to
give a user read access to some tables and write access to others simply by
keeping them in different databases!
--user
option to mysqld
, to allow it to run
as another Unix user (if it is started as the Unix root
user).
mysqladmin password 'new_password'
. This uses encrypted passwords
that are not logged in the normal MySQL log!
SELECT
code to handle some very specific queries
involving group functions (like COUNT(*)
) without a GROUP BY
but
with HAVING
. The following now works:
mysql> SELECT count(*) as C FROM table HAVING C > 1;
malloc()
.
-T32
option to mysqld
, for running all requêtesunder the
main thread. This makes it possible to debug mysqld
under Linux with
gdb
!
not_null_column IS NULL
(needed for some Access
queries).
STRAIGHT_JOIN
to be used between two tables to force the optimizer
to join them in a specific order.
VARCHAR
rather than CHAR
and
the column type is now VARCHAR
for fields saved as VARCHAR
.
This should make the MyODBC driver better, but may break some old
MySQL clients that don't handle FIELD_TYPE_VARCHAR
the same
way as FIELD_TYPE_CHAR
.
CREATE INDEX
and DROP INDEX
are now implemented through
ALTER TABLE
.
CREATE TABLE
is still the recommended (fast) way to create indexes.
--set-variable
option wait_timeout
to mysqld
.
mysqladmin processlist
to show how long a query
has taken or how long a thread has slept.
show variables
and some new to
show status
.
YEAR
. YEAR
is stored in 1 byte with allowable
values of 0, and 1901 to 2155.
DATE
type that is stored in 3 bytes rather than 4 bytes.
All new tables are created with the new date type if you don't use the
--old-protocol
option to mysqld
.
Error from table handler: #
on some operating systems.
--enable-assembler
option to configure
, for x86 machines
(tested on Linux + gcc
). This will enable assembler functions for the
most important string functions for more speed!
SIGHUP
to mysqld
;
mysqld
core dumped when starting from boot on some systems.
DELETE FROM nom_table
without a WHERE
condition is now done the
long way when you use LOCK TABLES
or if the table is in use, to
avoid race conditions.
INSERT INTO TABLE (timestamp_column) VALUES (NULL);
didn't set timestamp.
mysqladmin
refresh
often. This could in some very rare cases corrupt the header of the
index file and cause error 126 or 138.
refresh()
when running with the --skip-locking
option.
There was a ``very small'' time gap after a mysqladmin refresh
when
a table could be corrupted if one thread updated a table while another
thread did mysqladmin refresh
and another thread started a new update
ont the same table before the first thread had finished.
A refresh (or --flush-tables
) will now not return until all used tables
are closed!
SELECT DISTINCT
with a WHERE
clause that didn't match any rows
returned a row in some contexts (bug only in 3.21.31).
GROUP BY
+ ORDER BY
returned one empty row when no rows where
found.
Use_count: Wrong count for ...
in the error log file.
TINYINT
type on Irix.
LEFT("constant_string",function)
.
FIND_IN_SET()
.
LEFT JOIN
core dumped if the second table is used with a constant
WHERE/ON
expression that uniquely identifies one record.
DATE_FORMAT()
and incorrect dates.
DATE_FORMAT()
now ignores '%'
to make it possible to extend
it more easily in the future.
mysql
now returns an exit code > 0 if the query returned an error.
mysql
client.
By Tommy Larsen tommy@mix.hive.no.
safe_mysqld
to redirect startup messages to
'hostname'.err
instead
of 'hostname'.log
to reclaim file space on mysqladmin refresh
.
ENUM
always had the first entry as default value.
ALTER TABLE
wrote two entries to the update log.
sql_acc()
now closes the mysql
grant tables after a reload to
save table space and memory.
LOAD DATA
to use less memory with tables and BLOB
columns.
SELECT
problem with LEFT()
when using the czech character
set.
isamchk
; it couldn't repair a packed table in a very
unusual case.
SELECT
statements with &
or |
(bit functions) failed on
columns with NULL
values.
LOCK TABLES
+ DELETE from nom_table
never removed locks properly.
OR
function.
umask()
and creating new databases.
SELECT ... INTO OUTFILE ...
MIN(integer)
or MAX(integer)
in
GROUP BY
.
WEEK("XXXX-xx-01")
.
Error from table handler: #
on some operating systems.
GET_LOCK(string,timeout)
,
RELEASE_LOCK(string)
.
opened_tables
to show status
.
mysqld
through telnet + TCP/IP.
WHERE key_part_1 >= something AND key_part_2 <= something_else
.
configure
for detection of FreeBSD 3.0 9803xx and above
WHERE
with string_column_key = constant_string didn't always find
all rows if the column had many values differing only with characters of
the same sort value (like e and 'e).
umask()
to make log files non-readable for normal users.
--old-protocol
option to mysqld
.
SELECT
which matched all key fields returned the values in the
case of the matched values, not of the found values. (Minor problem.)
FROM_DAYS(0)
now returns "0000-00-00".
DATE_FORMAT()
, PM and AM were swapped for hours 00 and 12.
BLOB
/TEXT
in GROUP BY
with many
tables.
ENUM
field that is not declared NOT NULL
has NULL
as
the default value.
(Previously, the default value was the first enumeration value.)
INDEX (Organization,Surname(35),Initials(35))
.
SELECT ... FROM many_tables
much faster.
accept()
to possibly fix some problems on some
Linux machines.
typedef 'string'
to typedef 'my_string'
for better
portability.
isamchk
. Try isamchk --help
.
filesort()
didn't work.
Affects DISTINCT
, ORDER BY
and GROUP BY
on 64-bit
processors.
SELECT
on the
table.
OR
operators on key parts
inside each other.
MIN()
and MAX()
to work properly with strings and
HAVING
.
0664
to 0660
.
LEFT JOIN
and constant expressions in the ON
part.
configure
now works better on OSF1 (tested on 4.0D).
LIKE
optimization with international character
support.
DBI
to 0.93.
TIME
, DATE
, TIMESTAMP
, TEXT
, BIT
,
ENUM
, NO
, ACTION
, CHECK
, YEAR
,
MONTH
, DAY
, HOUR
, MINUTE
, SECOND
,
STATUS
, VARIABLES
.
TIMESTAMP
to NULL
in LOAD DATA INFILE ...
didn't
set the current time for the TIMESTAMP
.
BETWEEN
to recognize binary strings. Now BETWEEN
is
case sensitive.
--skip-thread-priority
option to mysqld
, for systems
where mysqld
's thread scheduling doesn't work properly (BSDI 3.1).
DAYNAME()
and MONTHNAME()
.
TIME_FORMAT()
. This works like DATE_FORMAT()
,
but takes a time string ('HH:MM:DD'
) as argument.
OR
s of key parts
inside AND
s.
variables
to mysqladmin
.
ALTER TABLE
to work with Win32 (Win32 can't rename open files).
Also fixed a couple of small bugs in the Win32 version.
crash-me
and the benchmarks on
the following platforms: SunOS 5.6 sun4u, SunOS 5.5.1 sun4u, SunOS 4.14 sun4c,
SunOS 5.6 i86pc, Irix 6.3 mips5k, HP-UX 10.20 hppa, AIX 4.2.1 ppc,
OSF1 V4.0 alpha, FreeBSD 2.2.2 i86pc and BSDI 3.1 i386.
COUNT(*)
problems when the WHERE
clause didn't match any
records. (Bug from 3.21.17.)
NULL = NULL
is true. Now you must use IS NULL
or IS NOT NULL
to test whether or not a value is NULL
.
(This is according to ANSI SQL but may break
old applications that are ported from mSQL
.)
You can get the old behavior by compiling with -DmSQL_COMPLIANT
.
LEFT OUTER JOIN
clauses.
ORDER BY
on string formula with possible NULL
values.
DAYOFYEAR()
, DAYOFMONTH()
, MONTH()
,
YEAR()
, WEEK()
, QUARTER()
, HOUR()
, MINUTE()
,
SECOND()
and FIND_IN_SET()
.
SHOW VARIABLES
.
mysql> SELECT 'first ' 'second'; -> 'first second'
mysqlaccess
to 2.02.
LIKE
.
WHERE data_field = date_field2 AND date_field2 = constant
.
SHOW STATUS
.
mysqladmin stat
to return the right number of queries.
AUTO_INCREMENT
attribute or is a TIMESTAMP
. This is needed for
the new Java driver.
configure
bugs and increased maximum table size
from 2G to 4G.
DBD
to 1823. This version implements mysql_use_result
in
DBD-Mysql
.
REVERSE()
(by Zeev Suraski).
DBI
to 0.91.
LEFT OUTER JOIN
.
CROSS JOIN
syntax. CROSS
is now a reserved word.
yacc
/bison
stack allocation to be even safer and to allow
MySQL to handle even bigger expressions.
ORDER BY
was slow when used with key ranges.
--with-unix-socket-path
to avoid
confusion.
LEFT OUTER JOIN
.
LEFT
, NATURAL
,
USING
.
MYSQL_HOST
as the default host if it's defined.
SELECT column, SUM(expr)
now returns NULL
for column
when
there are matching rows.
BLOB
s with ASCII
characters over 127.
mysqld
restart if one thread was reading data that another thread modified.
LIMIT offset,count
didn't work in INSERT ... SELECT
.
POWER()
, SPACE()
,
COT()
, DEGREES()
, RADIANS()
, ROUND(2 arg)
and TRUNCATE()
.
LOCATE()
parameters were
swapped according to ODBC standard. Fixed.
TIME_TO_SEC()
.
NOT NULL
fields.
UPDATE SET ...
statements.
BLOB
and TEXT
, to
be compatible with mysqldump
.
mysqlperl
is now from
Msql-Mysql-modules. This means that connect()
now takes
host
, database
, user
, password
arguments! The old
version took host
, database
, password
, user
.
DATE '1997-01-01'
, TIME '12:10:10'
and
TIMESTAMP '1997-01-01 12:10:10'
formats required by ANSI SQL.
WARNING: INCOMPATIBLE CHANGE!! This has the unfortunate
side-effect that you no longer can have columns named DATE
, TIME
or TIMESTAMP
. :( Old columns can still be accessed through
tablename.columnname
!)
make
programs trying to rebuild it.
readline
library upgraded to version 2.1.
DBI
/DBD
is now included in the distribution. DBI
is now the recommended way to connect to MySQL from Perl.
DBD
, with test results from
mSQL
2.0.3, MySQL, PostgreSQL 6.2.1 and Solid server 2.2.
crash-me
is now included with the benchmarks; This is a Perl program
designed to find as many limits as possible in a SQL server. Tested with
mSQL
, PostgreSQL, Solid and MySQL.
mysql
command line tool, by Zeev
Suraski and Andi Gutmans.
REPLACE
that works like INSERT
but
replaces conflicting records with the new record. REPLACE INTO
TABLE ... SELECT ...
works also.
CREATE DATABASE nom_base_de_donnees
and DROP
DATABASE nom_base_de_donnees
.
RENAME
option to ALTER TABLE
: ALTER TABLE name
RENAME AS new_name
.
make_binary_distribution
now includes `libgcc.a' in
`libmysqlclient.a'. This should make linking work for people who don't
have gcc
.
net_write()
to my_net_write()
because of a name
conflict with Sybase.
DAYOFWEEK()
compatible with ODBC.
bison
memory overrun checking to make MySQL
safer with weird queries.
configure
problems on some platforms.
DATE_FORMAT()
.
NOT IN
.
{fn now() }
DATE
and TIME
values with NULL
.
FLOAT
. Previously, the
values were converted to INT
s before sorting.
key_column=constant
.
DOUBLE
values sorted on integer results instead.
mysql
no longer needs a database argument.
HAVING
should be. According to ANSI, it should
be after GROUP BY
but before ORDER BY
. MySQL 3.20
incorrectly had it last.
USE DATABASE
to start using another database.
mysqld
doesn't crash even if you haven't done a
ulimit -n 256
before starting mysqld
.
errno
.
This makes Linux systems much safer!
SELECT
.
LIKE
on number key.
--table
option to mysql
to print in table format.
Moved time and row information after query result.
Added automatic reconnect of lost connections.
!=
as a synonym for <>
.
VERSION()
to make easier logs.
ftruncate()
call in MIT-pthreads. This made isamchk
destroy the `.ISM' files on (Free)BSD 2.x systems.
__P_
patch in MIT-pthreads.
NULL
if the returned string should be longer than max_allowed_packet
bytes.
INTERVAL
type to ENUM
, because
INTERVAL
is used in ANSI SQL.
JOIN
+ GROUP
+ INTO OUTFILE
,
the result wasn't grouped.
LIKE
with '_'
as last character didn't work. Fixed.
TRIM()
function.
CURTIME()
.
ENCRYPT()
function by Zeev Suraski.
FOREIGN KEY
syntax skipping. New reserved words:
MATCH
, FULL
, PARTIAL
.
mysqld
now allows IP number and hostname to the --bind-address
option.
SET OPTION CHARACTER SET cp1251_koi8
to enable conversions of
data to/from cp1251_koi8.
CREATE COLUMN
syntax of NOT NULL
columns to be after
the DEFAULT
value, as specified in the ANSI SQL standard. This will
make mysqldump
with NOT NULL
and default values incompatible with
MySQL 3.20.
ALTER TABLE nom_table ALTER COLUMN nom_colonne SET DEFAULT
NULL
.
CHAR
and BIT
as synonyms for CHAR(1)
.
INSERT ... SELECT ... GROUP BY
didn't work in some cases. An
Invalid use of group function
error occurred.
LIMIT
, SELECT
now always uses keys instead of record
scan. This will give better performance on SELECT
and a WHERE
that matches many rows.
BIT_OR()
and BIT_AND()
.
CHECK
and REFERENCES
.
CHECK
is now a reserved word.
ALL
option to GRANT
for better compatibility. (GRANT
is still a dummy function.)
ORDER BY
and GROUP BY
with NULL
columns.
last_insert_id()
to retrieve last AUTO_INCREMENT
value. This is intended for clients to ODBC that can't use the
mysql_insert_id()
API function, but can be used by any client.
--flush-logs
option to mysqladmin
.
STATUS
to mysql
.
ORDER BY
/GROUP BY
because of bug in gcc
.
INSERT ... SELECT ... GROUP BY
.
mysqlaccess
.
CREATE
now supports all ODBC types and the mSQL
TEXT
type.
All ODBC 2.5 functions are also supported (added REPEAT
). This provides
better portability.
TINYTEXT
, TEXT
, MEDIUMTEXT
and
LONGTEXT
. These are actually BLOB
types, but all searching is
done in case-insensitive fashion.
BLOB
fields are now TEXT
fields. This only
changes that all searching on strings is done in case-sensitive fashion.
You must do an ALTER TABLE
and change the field type to BLOB
if you want to have tests done in case-sensitive fashion.
configure
issues.
test-select
works.
--enable-unix-socket=pathname
option to configure
.
SUM()
functions.
For example, you can now use SUM(column)/COUNT(column)
.
PI()
, ACOS()
, ASIN()
, ATAN()
, COS()
,
SIN()
and TAN()
.
net_print()
in `procedure.cc'.
SELECT ... INTO OUTFILE
syntax.
GROUP BY
and SELECT
on key with many values.
mysql_fetch_lengths()
sometimes returned incorrect lengths when you used
mysql_use_result()
. This affected at least some cases of
mysqldump --quick
.
WHERE const op field
.
NULL
fields.
--pid-file=#
option to mysqld
.
FROM_UNIXTIME()
, originally by Zeev Suraski.
BETWEEN
in range optimizer (Did only test = of the first
argument).
mysql_errno()
, to get the error number of
the error message. This makes error checking in the client much easier.
This makes the new server incompatible with the 3.20.x server when running
without --old-protocol
. The client code is backward compatible.
More information can be found in the `README' file!
sigwait
and sigset
defines).
configure
should now be able to detect the last argument to
accept()
.
-O tmp_table_size=#
to mysqld
.
FROM_UNIXTIME(timestamp)
which returns a date string in
'YYYY-MM-DD HH:MM:DD' format.
SEC_TO_TIME(seconds)
which returns a string in
'HH:MM:SS' format.
SUBSTRING_INDEX()
, originally by Zeev Suraski.
mysqld
doesn't work on it yet.
pthread_create
to work.
mysqld
doesn't accept hostnames that start with digits followed by a
'.'
, because the hostname may look like an IP number.
--skip-networking
option to mysqld
, to only allow socket
connections. (This will not work with MIT-pthreads!)
free()
that killed the server on
CREATE DATABASE
or DROP DATABASE
.
mysqld
-O
options to better names.
-O join_cache_size=#
option to mysqld
.
-O max_join_size=#
option to mysqld
, to be able to set a
limit how big requêtes(in this case big = slow) one should be able to handle
without specifying SET OPTION SQL_BIG_SELECTS=1
. A # = is about 10
examined records. The default is ``unlimited''.
TIME
, DATE
, DATETIME
or TIMESTAMP
column to a constant, the constant is converted to a time value before
performing the comparison.
This will make it easier to get ODBC (particularly Access97) to work with
the above types. It should also make dates easier to use and the comparisons
should be quicker than before.
query()
in
mysqlperl
to take a query with \0
in it.
YYMMDD
) didn't work.
UPDATE
clause.
SELECT * INTO OUTFILE
, which didn't correctly if the outfile already
existed.
mysql
now shows the thread ID when starting or doing a reconnect.
--new
, but it crashes core a lot yet...
isam
library should be relatively 64-bit clean.
isamchk
which can detect and fix more problems.
isamlog
.
mysqladmin
: you can now do mysqladmin kill 5,6,7,8
to kill
multiple threads.
-O backlog=#
option to mysqld
.
ALTER TABLE
now returns warnings from field conversions.
ASCII()
.
BETWEEN(a,b,c)
. Use the standard ANSI
synax instead: expr BETWEEN expr AND expr
.
SUM()
functions.
nom_table.field_name
in UPDATE
.
SELECT DISTINCT
when using 'hidden group'. For example:
mysql> SELECT DISTINCT MOD(some_field,10) FROM test GROUP BY some_field;Note:
some_field
is normally in the SELECT
part. ANSI SQL should
require it.
INTERVAL
, EXPLAIN
, READ
,
WRITE
, BINARY
.
CHAR(num,...)
.
IN
. This uses a binary search to find a match.
LOCK TABLES nom_table [AS alias] {READ|WRITE} ...
--log-update
option to mysqld
, to get a log suitable for
incremental updates.
EXPLAIN SELECT ...
to get information about how the
optimizer will do the join.
FIELD_TYPE_TINY_BLOB
, FIELD_TYPE_MEDIUM_BLOB
,
FIELD_TYPE_LONG_BLOB
or FIELD_TYPE_VAR_STRING
(as
previously returned by mysql_list_fields
). You should instead only use
FIELD_TYPE_BLOB
or FIELD_TYPE_STRING
. If you want exact
types, you should use the command SHOW FIELDS
.
0x######
which can be used as a string
(default) or a number.
FIELD_TYPE_CHAR
is renamed to FIELD_TYPE_TINY
.
DEFAULT
values no longer need to be NOT NULL
.
ENUM
SET
double
or long long
.
This will provide the full 64-bit range with bit functions and fix some
conversions that previously could result in precision losses. One should
avoid using unsigned long long
columns with full 64-bit range
(numbers bigger than 9223372036854775807) because calculations are done
with signed long long
.
ORDER BY
will now put NULL
field values first. GROUP BY
will also work with NULL
values.
WHERE
with expressions.
mysql> SELECT * FROM nom_table WHERE key_part_1="customer" AND key_part_2>=10 AND key_part_2<=10;
Changes from 3.20.18 to 3.20.32b are not documented here since the 3.21 release branched here. And the relevant changes are also documented as changes to the 3.21 version.
-p#
(remove #
directories from path) to isamlog
.
All files are written with a relative path from the database directory
Now mysqld
shouldn't crash on shutdown when using the
--log-isam
option.
mysqlperl
version. It is now compatible with msqlperl-0.63
.
DBD
module available at http://www.mysql.com/Contrib
site.
STD()
(standard deviation).
mysqld
server is now compiled by default without debugging
information. This will make the daemon smaller and faster.
--basedir
option to
mysqld
. All other paths are relative in a normal installation.
BLOB
columns sometimes contained garbage when used with a SELECT
on more than one table and ORDER BY
.
GROUP BY
work as expected
(ANSI SQL extension).
Example:
mysql> SELECT id,id+1 FROM table GROUP BY id;
MYSQL_PWD
was reversed. Now MYSQL_PWD
is
enabled as default in the default release.
mysqld
to core dump with
Arithmetic error on Sparc-386.
--unbuffered
option to mysql
, for new mysqlaccess
.
BLOB
columns and the functions IS NULL
and
IS NOT NULL
in the WHERE
clause.
max_allowed_packet
is now 64K for
the server and 512K for the client. This is mainly used to catch
incorrect packets that could trash all memory. The server limit may be
changed when it is started.
safe_mysqld
to check for running daemon.
ELT()
function is renamed to FIELD()
. The new
ELT()
function returns a value based on an index: FIELD()
is the inverse of ELT()
Example: ELT(2,"A","B","C")
returns
"B"
. FIELD("B","A","B","C")
returns 2
.
COUNT(field)
, where field
could have a NULL
value, now
works.
SELECT ... GROUP BY
.
WHERE
with many unoptimizable brace levels.
get_hostname
, only the IP is checked.
Previously, you got Access denied
.
INSERT INTO ... SELECT ... WHERE
could give the error
Duplicated field
.
safe_mysqld
to make it ``safer''.
LIKE
was case sensitive in some places and case insensitive in others.
Now LIKE
is always case insensitive.
'#'
anywhere on the line.
SET OPTION SQL_SELECT_LIMIT=#
. See the FAQ for more details.
mysqlaccess
script.
FROM_DAYS()
and WEEKDAY()
to also take a full
TIMESTAMP
or DATETIME
as argument. Before they only took a
number of type YYYYMMDD
or YYMMDD
.
UNIX_TIMESTAMP(timestamp_column)
.
mysqld
to work around a bug in MIT-pthreads. This makes multiple
small SELECT
operations 20 times faster. Now lock_test.pl
should
work.
mysql_FetchHash(handle)
to mysqlperl
.
mysqlbug
script is now distributed built to allow for reporting
bugs that appear during the build with it.
getpwuid()
instead of
cuserid()
.
SELECT
optimizer when using many tables with the same
column used as key to different tables.
GRANT
command to satisfy Powerbuilder.
packets out of order
when using MIT-pthreads.
fcntl()
fails. Thanks to Mike Bretz for finding this bug.
termbits
from `mysql.cc'. This conflicted with
glibc
2.0.
SELECT
as superuser without a database.
SELECT
with group calculation to outfile.
-p
or --password
option to mysql
without
an argument, the user is solicited for the password from the tty.
MYSQL_PWD
(by Elmar Haneke).
kill
to mysqladmin
to kill a specific
MySQL thread.
AUTO_INCREMENT
key with ALTER TABLE
.
AVG()
gave too small value on some SELECT
s with
GROUP BY
and ORDER BY
.
DATETIME
type (by Giovanni Maruzzelli
DONT_USE_DEFAULT_FIELDS
works.
CREATE INDEX
.
DATE
, TIME
and
TIMESTAMP
.
OR
of multiple tables (gave empty set).
DATE
and TIME
types.
SELECT
with AND
-OR
levels.
LIMIT
and ORDER BY
.
ORDER BY
and GROUP BY
on items that aren't in the
SELECT
list.
(Thanks to Wim Bonis bonis@kiss.de, for pointing this out.)
INSERT
.
SELECT ... WHERE ... = NULL
.
glibc
2.0. To get glibc
to work, you should
add the `gibc-2.0-sigwait-patch' before compiling glibc
.
ALTER TABLE
when changing a NOT NULL
field to
allow NULL
values.
CREATE TABLE
.
CREATE TABLE
now allows FLOAT(4)
and FLOAT(8)
to mean
FLOAT
and DOUBLE
.
mysqlaccess
by Yves.Carlier@rug.ac.be.
This program shows the access rights for a specific user and the grant
rows that determine this grant.
WHERE const op field
(by bonis@kiss.de).
SELECT ... INTO OUTFILE
, all temporary tables are ISAM
instead of HEAP to allow big dumps.
ALTER TABLE
according to SQL92.
--port
and --socket
options to all utility programs and
mysqld
.
readdir_r()
. Now mysqladmin create database
and mysqladmin drop database
should work.
tempnam()
. This should fix the ``sort
aborted'' bug.
sql_update
. This fixed slow updates
on first connection. (Thanks to Vaclav Bittner for the test.)
INSERT INTO ... SELECT ...
MEDIUMBLOB
fixed.
ALTER TABLE
and BLOB
s.
SELECT ... INTO OUTFILE
now creates the file in the current
database directory.
DROP TABLE
now can take a list of tables.
DESCRIBE
(DESC
).
make_binary_distribution
.
configure
's
C++ link test.
--without-perl
option to configure
.
ALTER TABLE
didn't copy null bit. As a result, fields that were allowed
to have NULL
values were always NULL
.
CREATE
didn't take numbers as DEFAULT
.
ALTER TABLE
and multi-part keys.
ALTER TABLE
, SELECT ... INTO OUTFILE
and
LOAD DATA INFILE
.
NOW()
.
mysql/user
table.
add_file_priv
which adds the new field file_priv
to the user
table. This script must be executed if you want to
use the new SELECT ... INTO
and LOAD DATA INFILE ...
commands
with a version of MySQL earlier than 3.20.7.
lock_test.pl
test fail.
status
to mysqladmin
for short logging.
-k
option to mysqlshow
, to get key information for a table.
mysqldump
.
configure
cannot find a -lpthreads
library.
program --help
.
RAND([init])
.
sql_lex
to handle \0
unquoted, but the client can't send
the query through the C API, because it takes a str pointer.
You must use mysql_real_query()
to send the query.
mysql_get_client_info()
.
mysqld
now uses the N_MAX_KEY_LENGTH
from `nisam.h' as
the maximum allowed key length.
mysql> SELECT filter_nr,filter_nr FROM filter ORDER BY filter_nr;Previously, this resulted in the error:
Column: 'filter_nr' in order clause is ambiguous
.
mysql
now outputs '\0'
, '\t'
, '\n'
and '\\'
when encountering ASCII 0, tab, newline or '\'
while writing
tab-separated output.
This is to allow printing of binary data in a portable format.
To get the old behavior, use -r
(or --raw
).
mysql_fetch_lengths(MYSQL_RES *)
, which
returns an array of of column lengths (of type uint
).
IS NULL
in WHERE
clause.
SELECT
option STRAIGHT_JOIN
to tell the optimizer that
it should join tables in the given order.
'--'
in `mysql.cc'
(Postgres syntax).
SELECT
expressions and table columns in a SELECT
which are not used in the group part. This makes it efficient to implement
lookups. The column that is used should be a constant for each group because
the value is calculated only once for the first row that is found for a group.
mysql> SELECT id,lookup.text,sum(*) FROM test,lookup WHERE test.id=lookup.id GROUP BY id;
SUM(function)
(could cause a core dump).
AUTO_INCREMENT
placement in the SQL query:
INSERT into table (auto_field) values (0);inserted 0, but it should insert an
AUTO_INCREMENT
value.
mysql
now allows doubled ''
or ""
within strings for
embedded '
or "
.
EXP()
, LOG()
, SQRT()
, ROUND()
, CEILING()
.
configure
source now compiles a thread-free client library
-lmysqlclient
. This is the only library that needs to be linked
with client applications. When using the binary releases, you must
link with -lmysql -lmysys -ldbug -lstrings
as before.
readline
library from bash-2.0
.
configure
and makefiles (and related source).
VPATH
. Tested with GNU Make 3.75.
safe_mysqld
and mysql.server
changed to be more compatible
between the source and the binary releases.
LIMIT
now takes one or two numeric arguments.
If one argument is given, it indicates the maximum number of rows in
a result. If two arguments are given, the first argument indicates the offset
of the first row to return, the second is the maximum number of rows.
With this it's easy to do a poor man's next page/previous page WWW
application.
FIELDS()
to ELT()
.
Changed SQL function INTERVALL()
to INTERVAL()
.
SHOW COLUMNS
a synonym for SHOW FIELDS
.
Added compatibility syntax FRIEND KEY
to CREATE TABLE
. In
MySQL, this creates a non-unique key on the given columns.
CREATE INDEX
and DROP INDEX
as compatibility functions.
In MySQL, CREATE INDEX
only checks if the index exists and
issues an error if it doesn't exist. DROP INDEX
always succeeds.
sql_acl
(core on new connection).
host
, user
and db
tables from database test
in the distribution.
FIELD_TYPE_CHAR
can now be signed (-128 - 127) or unsigned (0 - 255)
Previously, it was always unsigned.
CONCAT()
and WEEKDAY()
.
mysqld
to be compiled with SunPro
compiler.
'('
immediately after the function name
(no intervening space).
For example, 'user('
is regarded as beginning a function call, and
'user ('
is regarded as an identifier user
followed by a
'('
, not as a function call.
configure
and Automake.
It will make porting much easier. The readline
library is included
in the distribution.
DBD
will follow when the new DBD
code
is ported.
mysqld
can now be started with Swedish
or English (default) error messages.
INSERT()
, RTRIM()
, LTRIM()
and
FORMAT()
.
mysqldump
now works correctly for all field types (even
AUTO_INCREMENT
). The format for SHOW FIELDS FROM nom_table
is changed
so the Type
column contains information suitable for CREATE TABLE
.
In previous releases, some CREATE TABLE
information had to be patched
when recreating tables.
BLOB
and TIMESTAMP
) are corrected.
TIMESTAMP
now returns different date information depending on its
create length.
'_'
.
DATABASE()
, USER()
, POW()
,
LOG10()
(needed for ODBC).
WHERE
with an ORDER BY
on fields from only one table,
the table is now preferred as first table in a multi-join.
HAVING
and IS NULL
or IS NOT NULL
now works.
SUM()
,
AVG()
...) didn't work together. Fixed.
mysqldump
: Didn't send password to server.
'Locked'
to process list as info if a query is
locked by another query.
IF(arg,syntax_error,syntax_error)
crashed.
CEILING()
, ROUND()
, EXP()
, LOG()
and SQRT()
.
BETWEEN
to handle strings.
SELECT
with grouping on BLOB
columns not to return
incorrect BLOB
info. Grouping, sorting and distinct on BLOB
columns will not yet work as
expected (probably it will group/sort by the first 7 characters in the
BLOB
). Grouping on formulas with a fixed string size (use MID()
on a BLOB
) should work.
BLOB
fields, the BLOB
was garbage on output.
DISTINCT
with calculated columns.
BLOB
ne peuvent pas être utilisées de manière ``sûre''
dans les clauses GROUP BY
, ORDER BY
ou DISTINCT
.
Seuls, les max_sort_length
premiers octets (par défaut 1024)
sont utilisés dans les comparaisons entre BLOB
.
Cela peut être changé avec l'option -O max_sort_length
de mysqld
.
Une solution pour contourner le problème est d'utiliser une sous chaîne :
SELECT DISTINCT LEFT(blob,2048) FROM nom_table
.
BIGINT
ou DOUBLE
(les deux font 64 bits de long).
La précision de calcul dépend de la fonction. La régle générale est que les fonctions de bits
sont fait en précision BIGINT
, IF
et ELT()
avec une précision
BIGINT
ou DOUBLE
, et le reste est fait en précision DOUBLE
.
Il vaut mieux éviter d'utiliser les valeurs non signées, supérieures à
63 bits(9223372036854775807) pour tout ce qui n'est pas champs de bits.
BLOB
et TEXT
, sont automatiquement débarassées
de leurs espaces de fin de chaînes. Pour les types CHAR
c'est bon, et peut même
être vu comme une fonctionnalité, d'après la norme ANSI SQL92. Le bug est que
MySQL traite les colonnes VARCHAR
de la même façon.
ENUM
et SET
dans une seule table.
UPDATE
qui modifiait une clé
avec une clause WHERE
sur la même clé pouvait échouer car la clé était utilisée pour
rechercher les lignes, et la même ligne risque d'avoir été trouvée plusieurs fois.
UPDATE nom_table SET KEY=KEY+1 WHERE KEY > 100;Pour contourner le problème, on pourvait utiliser la requête suivante :
mysql> UPDATE nom_table SET KEY=KEY+1 WHERE KEY+0 > 100;Cela va fonctionner, car MySQL ne va pas utiliser d'index dans les expressions qui sont dans la clause
WHERE
.
safe_mysqld
redirige tous les messages de mysqld
vers l'historique mysqld
.
Le problème est que si vous exécutez la commande mysqladmin refresh
pour
fermer et réouvrir l'historique,
stdout
et stderr
continue de pointer sur l'ancien fichier d'historique.
Si vous utilisez --log
extensivement, il vaut mieux éditer le fichier safe_mysqld
et y mettre `'hostname'.err' au lieu de `'hostname'.log' pour que vous puissiez
facilement récupérer l'espace de l'ancien fichier d'historique, en effacant l'ancient, et exécutant mysqladmin refresh
.
UPDATE
, les colonnes sont modifiées de gauche à droite.
Si vous faites référence à une colonne modifiée, vous allez utiliser la valeur modifiée, au lieu
d'utiliser la valeur originale.
Par exemple :
mysql> UPDATE nom_table SET KEY=KEY+1,KEY=KEY+1va mettre dans
KEY
la valeur 2
au lieu de 1
.
Pour les bugs spécifiques à chaque plate forme, reportez vous à la section sur la compilation et le portage.
Tout ce qui est dans cette liste est dans l'ordre de priorité. Si vous voulez pouvoir modifier l'ordre des priorités, prenez une licence ou un contrat de support, et dites nous ce qui vous manque le plus. 3 Support et licences MySQL.
select id from t where grp in (select grp from g where u > 100)
ALTER TABLE
sur une table qui est sous la forme d'un lien symbolique
sur un autre disque, commencer par créer une table temporaire sur le disque actuel.
RENAME table as table, table as table [,...]
DECRYPT()
.
FOREIGN
) dans le fichier `.frm'.
DEFAULT
aux colonnes.
Au contraire, retourner une erreur lors de l'insertion (INSERT
)
de valeur dans des colonnes sans valeur par défaut.
SELECT CACHED ....
mysql_query()
simultanées, sans lire les résultats, ou bien retourner une alerte lorsque cela
se passe.
BIT
pour qu'il ne prenne qu'un 1 bit (actuellement, BIT
prend un char).
ctime()
ne fonctionne pas avec certaines configurations FreeBSD.
ORDER BY
pour les modifications. Cela serait bien pratique avec des fonctions telles que generate_id(start,step)
.
IMAGE
pour les commandes LOAD DATA INFILE
afin qu'elle ne modifie pas
les champs TIMESTAMP
et AUTO_INCREMENT
.
LOAD DATA INFILE
comprenne les syntaxes du type :
LOAD DATA INFILE 'Nom_fichier.txt' INTO TABLE nom_table TEXT_FIELDS (champs_texte1, champs_texte2, champs_texte3) SET table_field1=concatenate(champs_texte1, champs_texte2), champs_texte3=23 IGNORE text_field3
MIN()
, MAX()
avec des chaînes (pas dans les fonctions de groupes).
Elles seraient alors synonymes de LEAST()
, GREATEST()
.
mysql
vers netscape.
LOCK DATABASES
. ( avec diverses options).
NATURAL JOIN
.
DECIMAL
et NUMERIC
ne peuvent pas comprendre les notations exponentielles :
Field_decimal::store(const char *from,uint len)
doivent être recodées pour corriger ceci.
mysql.cc
pour faire moins de malloc()
lors des hashages des noms de champs.
t1 JOIN t2 ON ...
et t1 JOIN t2 USING ...
Actuellement, c'est uniquement possible avec LEFT JOIN
.
unsigned long long
.
CASE
.
show status
. Notamment :
Commandes INSERT
/DELETE
/UPDATE
. Lignes lues et modifiées.
SELECT sur 1 table et SELECT avec jointures.Nombre moyen de tables dans un SELECT.
Nombre de lecture écriture du buffer de clé (logiques et réél).
ORDER BY
, GROUP BY
, tables temporaires créées.
mysql
est interrompu au milieu d'une requête, on devrait pouvoir être
capable d'ouvrir une autre connexion, et de tuer l'ancienne requête.
Alternativement, une tentative doit être faite pour detecter ceci au niveau du serveur.
SHOW INFO FROM nom_table
devrait être implémenté pour accéder à des informations basiques.
mysqld
de supporter plusieurs jeu de caractères en même temps.
NATURAL JOIN
.
CONNECT BY PRIOR ...
pour rechercher dans les structures hiérarchiques.
RENAME DATABASE
mysqladmin copy database new-database
.
IGNORE
pour la commande UPDATE
(Elle effacerait les lignes qui ont une clé en doublon, lors de la modification).
select distinct a from foo order by b
ne devrait pas retourner les lignes en doubles,
Si il y a différents couples (a,b)
DATETIME
pour enregistrer les fractions de seconds.
NULL
pour les calculs de colonnes.
get_changed_tables(timeout,table1,table2,...)
LAST_UPDATED(nom_table)
update items,month set items.price=month.price where items.id=month.id;
SHOW
.
SET TIMESTAMP=#;
UNION
, MINUS
, INTERSECT
et FULL OUTER JOIN
.
(Actuellement seul LEFT OUTER JOIN
est supporté)
UNIQUE
sur des champs qui peuvent être NULL
.
SQL_OPTION MAX_SELECT_TIME=#
pour mettre une limite de temps à une requête.
LIMIT
commence à lire les résultats depuis la fin.
mysqld
qui ne soit pas multithreaded (3-5 jours).
safe_mysqld
: suivant la norme FSSTND (que
Debian essaie de suivre) les fichiers PID doivent être stockés dans `/var/run/<nom_du_programme>.pid'
et les fichiers de logs dans `/var/log'. Il serait pas mal de pouvoir
mettre "DATADIR" dans la première déclaration d'un "pidfile" et "log" : cela permettrait
de modifier l'emplacement de ces fichiers d'une seule commande.
UPDATE SET blob=read_blob_from_file('my_gif') where id=1;
zlib()
pour dégzip
per les fichiers avec LOAD DATA INFILE
.
BLOB
.
AUTO_INCREMENT
lorsque
la valeur passée est 0.
Utiliser plutôt le code NULL
.
JOIN
avec parenthèses.
Le temps est donné en quantité de travail, et non pas en temps réel. Le coeur de métier de TcX's est l'utilisation de MySQL et non pas son developpement. Mais comme TcX est une société très souple, elle a attribué beaucoup de ressources au developpement de MySQL.
SELECT
s, et
comme nous n'utilisons pas de transactions, nous pouvons être bien plus rapide
que les autres serveurs. Nous allons accepter des opérations atomiques sur les tables
multiples. Actuellement, des opérations atomiques peuvent être faites avec
LOCK TABLES
/UNLOCK TABLES
mais nous rendrons cette manipulation
automatique dans le futur.
A working Posix thread library is needed for the server. On Solaris 2.5 we use SUN PThreads (the native thread support in 2.4 and earlier versions are not good enough) and on Linux we use LinuxThreads by Xavier Leroy, Xavier.Leroy@inria.fr.
The hard part of porting to a new Unix variant without good native thread support is probably to port MIT-pthreads. See `mit-pthreads/README' and Programming POSIX Threads.
The MySQL distribution includes a patched version of Provenzano's Pthreads from MIT (see MIT Pthreads web page). This can be used for some operating systems that do not have POSIX threads.
It is also possible to use another user level thread package named FSU Pthreads (see FSU Pthreads home page). This implementation is being used for the SCO port.
See the `thr_lock.c' and `thr_alarm.c' programs in the `mysys' directory for some tests/examples of these problems.
Both the server and the client need a working C++ compiler (we use gcc
and have tried SparcWorks). Another compiler that is known to work is the
Irix cc
.
To compile only the client use ./configure --without-server
.
There is currently no support for only compiling the server. Nor is it likly to be added unless someone has a good reason for it.
If you want/need to change any `Makefile' or the configure script you must
get Automake and Autoconf. We have used the automake-1.2
and
autoconf-2.12
distributions.
All steps needed to remake everything from the most basic files.
/bin/rm */.deps/*.P /bin/rm -f config.cache aclocal autoheader aclocal automake autoconf ./configure --with-debug --prefix='your installation directory' # The makefiles generated above need GNU make 3.75 or newer. # (called gmake below) gmake clean all install init-db
If you run into problems with a new port, you may have to do some debugging of MySQL! G.1 Debugguer un serveur MySQL.
Note: Before you start debugging mysqld
, first get the test
programs mysys/thr_alarm
and mysys/thr_lock
to work. This
will ensure that your thread installation has even a remote chance to work!
If you are using some functionality that is very new in MySQL,
you can try to run mysqld with the --skip-new
(which will disable all
new, potentially unsafe functionality) or with --safe-mode
which
disables a lot of optimization that may cause problems.
18.1 Que faire si MySQL plante constamment?.
If mysqld
doesn't want to start, you should check that you don't have
any my.cnf
file that interferes with your setup!
You can check your my.cnf
arguments with mysqld --print-defaults
and avoid using them by starting with mysqld --no-defaults ...
.
If you have some very specific problem, you can always try to debug
MySQL. To do this you must configure MySQL with the
option --with-debug
. You can check whether or not
MySQL was compiled with debugging by doing: mysqld
--help
. If the --debug
flag is listed with the options then you
have debugging enabled. mysqladmin ver
also lists the
mysqld
version as mysql ... -debug
in this case.
If you are using gcc or egcs, the recommended configure line is:
CC=gcc CFLAGS="-O6" CXX=gcc CXXFLAGS="-O6 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-debug
This will avoid problems with the libstdc++ library and with C++ exceptions.
If you can cause the mysqld
server to crash quickly, you can try to
create a trace file of this:
Start the mysqld
server with a trace log in `/tmp/mysql.trace'.
The log file will get very BIG.
mysqld --debug --log
or you can start it with
mysqld --debug=d,info,error,query,general,where:O,/tmp/mysql.trace
which only prints information with the most interesting tags.
When you configure MySQL for debugging you automatically enable a
lot of extra safety check functions that monitor the health of mysqld
.
If they find something ``unexpected,'' an entry will be written to
stderr
, which safe_mysqld
directs to the error log! This also
means that if you are having some unexpected problems with MySQL and
are using a source distribution, the first thing you should do is to
configure MySQL for debugging! (The second thing, of course, is to
send mail to mysql@lists.mysql.com and ask for help. Please use the
mysqlbug
script for all bug reports or questions regarding the
MySQL version you are using!
On most system you can also start mysqld
from gdb
to get
more information if mysqld
crashes.
With some gdb
versions on Linux you must use run --one-thread
if
you want to be able to debug mysqld
threads. In this case you
can only have one thread active at a time.
If you are using gdb 4.17.x on Linux, you should install a `.gdb' file, with the following information, in your current directory:
set print sevenbit off handle SIGUSR1 nostop noprint handle SIGUSR2 nostop noprint handle SIGWAITING nostop noprint handle SIGLWP nostop noprint handle SIGPIPE nostop handle SIGALRM nostop handle SIGHUP nostop handle SIGTERM nostop noprint
Here follows an example how to debug mysqld:
shell> gdb /usr/local/libexec/mysqld gdb> run ... back # Do this when mysqld crashes info locals up info locals up ... (until you get some information about local variables) quit
Include the above output in a mail generated with mysqlbug
and
mail this to mysql@lists.mysql.com
.
If mysqld
hangs you can try to use some system tools like
strace
or /usr/proc/bin/pstack
to examine where
mysqld
has hanged.
If mysqld
starts to eat up CPU or memory or if it ``hangs'', you
can use mysqladmin processlist status
to find out if someone is
executing some query that takes a long time. It may be a good idea to
run mysqladmin -i10 processlist status
in some window if you are
experiencing performance problems or problems when new clients can't connect.
If mysqld
dies or hangs, you should start mysqld
with
--log
. When mysqld
dies again, you can check in the log file
for the query that killed mysqld
. Note that before starting
mysqld
with --log
you should check all your tables with
isamchk
. 13 Maintenance d'un serveur MySQL.
If you are using a log file, mysqld --log
, you should check the
'hostname' log files, that you can find in the database directory, for
any requêtesthat could cause a problem. Try the command EXPLAIN
on all SELECT
statements that takes a long time to ensure that
mysqld are using indexes properly. EXPLAIN
. You
should also test complicated requêtesthat didn't complete within the
mysql
command line tool.
If you find the text mysqld restarted
in the error log file (normally
named `hostname.err') you have probably found a query that causes
mysqld
to fail. If this happens you should check all your tables with
isamchk
( 13 Maintenance d'un serveur MySQL), and test the requêtesin the
MySQL log files if someone doesn't work. If you find such a query,
try first upgrading to the newest MySQL version. If this doesn't
help and you can't find anything in the mysql
mail archive, you should
report the bug to mysql@lists.mysql.com. Links to mail archives are
available at the online MySQL
documentation page.
If you get corrupted tables or if mysqld
always fails after some
update commands, you can test if this bug is reproducible by doing the
following:
mysqladmin shutdown
)
isamchk -s database/*.ISM
. Repair any
wrong tables with isamchk -r database/table.ISM
.
mysqld
with --log-update
mysqld server
.
mysqld
server without --log-update
mysql < update-log
. The update log
is saved in the MySQL database directory with the name
your-hostname.#
.
ISAM
code! ftp the tables + the update log to
ftp://www.mysql.com/pub/mysql/secret and we will fix this as soon as
possible!
The command mysqladmin debug
will dump some information about
locks in use, used memory and query usage to the mysql log file. This
may help solve some problems. This command also provides some useful
information even if you haven't compiled MySQL for debugging!
If the problem is that some tables are getting slower and slower you
should try to repair the tables with isamchk
to optimize the
table layout. You should also check the slow requêteswith EXPLAIN
.
13 Maintenance d'un serveur MySQL.
You should also read the OS-specific section in this manual for problems that may be unique to your environment. 4.11 Quelques spécificités liées aux OS
If you are using the Perl DBI
interface, you can turn on
debugging information by using the trace
méthode or by
setting the DBI_TRACE
environment variable.
Perl DBI
Class.
To be able to debug a MySQL client with the integrated debug package,
you should configure MySQL with --with-debug
.
4.7.3 Options communes de configure
Before running a client, you should set the MYSQL_DEBUG
environment
variable:
shell> MYSQL_DEBUG=d:t:O,/tmp/client.trace shell> export MYSQL_DEBUG
This causes clients to generate a trace file in `/tmp/client.trace'.
If you have problems with your own client code, you should attempt to
connect to the server and run your query using a client that is known to
work. Do this by running mysql
in debugging mode (assuming you
have compiled MySQL with debugging on):
shell> mysql --debug=d:t:O,/tmp/client.trace
This will provide useful information in case you mail a bug report. 2.3 Comment rapporter des bugs et des problèmes.
If your client crashes at some 'legal' looking code, you should check that your `mysql.h' include file matches your mysql library file. A very common mistake is to use an old `mysql.h' file from an old MySQL installation with new MySQL library.
I have tried to use the RTS thread packages with MySQL but stumbled on the following problems:
They use old version of a lot of POSIX calls and it is very tedious to make wrappers for all functions. I am inclined to think that it would be easier to change the thread libraries to the newest POSIX specification.
Some wrappers are already written. See `mysys/my_pthread.c' for more info.
At least the following should be changed:
pthread_get_specific
should use one argument.
sigwait
should take two arguments.
A lot of functions (at least pthread_cond_wait
,
pthread_cond_timedwait
)
should return the error code on error. Now they return -1 and set errno
.
Another problem is that user-level threads use the ALRM
signal and this
aborts a lot of functions (read
, write
, open
...).
MySQL should do a retry on interrupt on all of these but it is
not that easy to verify it.
The biggest unsolved problem is the following:
To get thread-level alarms I changed `mysys/thr_alarm.c' to wait between
alarms with pthread_cond_timedwait()
, but this aborts with error
EINTR
. I tried to debug the thread library as to why this happens,
but couldn't find any easy solution.
If someone wants to try MySQL with RTS threads I suggest the following:
-DHAVE_rts_threads
.
thr_alarm
.
thr_alarm
. If it runs without any ``warning'', ``error'' or aborted
messages, you are on the right track. Here follows a successful run on
Solaris:
Main thread: 1 Tread 0 (5) started Thread: 5 Waiting process_alarm Tread 1 (6) started Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 1 (1) sec Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 2 (2) sec Thread: 6 Simulation of no alarm needed Thread: 6 Slept for 0 (3) sec Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 4 (4) sec Thread: 6 Waiting process_alarm thread_alarm Thread: 5 Slept for 10 (10) sec Thread: 5 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 5 (5) sec Thread: 6 Waiting process_alarm process_alarm ... thread_alarm Thread: 5 Slept for 0 (1) sec end
MySQL is very dependent on the thread package used. So when choosing a good platform for MySQL, the thread package is very important.
There are at least three types of thread packages:
ps
may show the different threads. If one thread aborts the
whole process aborts. Most system calls are thread-safe and should
require very little overhead. Solaris, HP-UX, AIX and OSF1 have kernel
threads.
In some systems kernel threads are managed by integrating user level threads in the system libraries. In such cases, the thread switching can only be done by the thread library and the kernel isn't really ``thread aware''.
Une expression régulière (regex) est une méthode puissante de rechercher des valeurs complexes.
MySQL utilise l'implémentation de Henry Spencer's. Cela permet d'être compatible avec POSIX 1003.2. MySQL utilise la version étendue.
Ce chapitre est une approche très simplifiée. Pour avoir tous les détails, allez sur le manuel d'Henry Spencer regex(7)
qui est inclus dans la distribution. C Contributions à MySQL.
Une expression régulière décrit un ensemble de chaînes. L'expression régulière la plus simple est celle qui ne contient aucun caractère spécial. Par exemple, bonjour
correspond à bonjour
et rien d'autre.
Les expressions régulières non triviales utilisent certains caractères spéciaux, ce qui leur permet de décrire plusieurs chaînes. Par exemple, l'expression régulière bonjour|le|monde
correspond soit à bonjour
, soit à le
ou encore à monde
Comme exemple plus complexe, la regexp B[an]*es
correspond à
Bananes
, Baaaaaes
, Bes
, Bans
et n'importe quelle
autre chaîne qui commence par B
, finit par es
, et contient
des a
et n
entre.
Une expression régulière peut contenir les caractères spéciaux suivants: caractères/explication:
^
mysql> select "fo\nfo" REGEXP "^fo$"; -> 0 mysql> select "fofo" REGEXP "^fo"; -> 1
$
mysql> select "fo\no" REGEXP "^fo\no$"; -> 1 mysql> select "fo\no" REGEXP "^fo$"; -> 0
.
mysql> select "fofo" REGEXP "^f.*"; -> 1 mysql> select "fo\nfo" REGEXP "^f.*"; -> 1
a*
a
(0 ou plus).
mysql> select "Ban" REGEXP "^Ba*n"; -> 1 mysql> select "Baaan" REGEXP "^Ba*n"; -> 1 mysql> select "Bn" REGEXP "^Ba*n"; -> 1
a+
a
existants (1 ou plus).
mysql> select "Ban" REGEXP "^Ba+n"; -> 1 mysql> select "Bn" REGEXP "^Ba+n"; -> 0
a?
a
(0 ou 1).
mysql> select "Bn" REGEXP "^Ba?n"; -> 1 mysql> select "Ban" REGEXP "^Ba?n"; -> 1 mysql> select "Baan" REGEXP "^Ba?n"; -> 0
de|abc
de
, soit abc
.
mysql> select "pi" REGEXP "pi|apa"; -> 1 mysql> select "axe" REGEXP "pi|apa"; -> 0 mysql> select "apa" REGEXP "pi|apa"; -> 1 mysql> select "apa" REGEXP "^(pi|apa)$"; -> 1 mysql> select "pi" REGEXP "^(pi|apa)$"; -> 1 mysql> select "pix" REGEXP "^(pi|apa)$"; -> 0
(abc)*
mysql> select "pi" REGEXP "^(pi)+$"; -> 1 mysql> select "pip" REGEXP "^(pi)+$"; -> 0 mysql> select "pipi" REGEXP "^(pi)+$"; -> 1
{1}
{2,3}
a*
a{0,}
.
a+
a{1,}
.
a?
a{0,1}
.
i
et aucune virgule, remplace n'importe quelle séquence de i
fois l'atome.
Un atome suivi par une limite, contenant un entier i
et une virgule, remplace n'importe quelle séquence de i
fois ou plus l'atome.
Un atome suivi par une limite, contenant un entier i
et une virgule et un autre entier j
, remplace n'importe quelle séquence de i
à j
(inclus) fois l'atome.
Les deux arguments doivent être 0 >= value <= RE_DUP_MAX (default 255)
.
Si il y a deux arguments, le second doit être supérieur au premier.
[a-dX]
[^a-dX]
a
, b
, c
, d
or X
.
Pour inclure le caractère litéral ]
, il doit être placé juste après le crochet ouvrant.
Pour inclure le caractère litéral -
character, il doit être en premier ou en dernier.
De cette façon, [0-9]
correspond à tous les chiffres.
Tous les autres caractères qui n'ont aucune signification entre []
ne fait que se remplacer lui même.
mysql> select "aXbc" REGEXP "[a-dXYZ]"; -> 1 mysql> select "aXbc" REGEXP "^[a-dXYZ]$"; -> 0 mysql> select "aXbc" REGEXP "^[a-dXYZ]+$"; -> 1 mysql> select "aXbc" REGEXP "^[^a-dXYZ]+$"; -> 0 mysql> select "gheis" REGEXP "^[^a-dXYZ]+$"; -> 1 mysql> select "gheisa" REGEXP "^[^a-dXYZ]+$"; -> 0
[[.characters.]]
ch
l'expressions régulière [[.ch.]]*c
correspond bien à chchcc
.
[=character-class=]
o
et (+)
sont membre d'une classe d'équivalence,
alors [[=o=]]
, [[=(+)=]]
, et [o(+)]
sont synonymes. Une classe d'équivalence ne peut pas être la fin d'un intervalle.
[:character_class:]
[:
et :]
correspond à la liste de tous les caractères de cette classe. Les noms de classes sont :
alnum | digit | punct |
alpha | graph | space |
blank | lower | upper |
cntrl | xdigit |
ctype(3)
du manuel.
Localement, on peut disposer d'autres classes.
Une classe de caractère ne peut pas être utilisé comme extrémité d'intervalle.
mysql> select "justalnums" REGEXP "[[:alnum:]]+"; -> 1 mysql> select "!!" REGEXP "[[:alnum:]]+"; -> 0
[[:<:]]
[[:>:]]
ctype(3)
) et l'underscore (_
).
mysql> select "a word a" REGEXP "[[:<:]]word[[:>:]]"; -> 1 mysql> select "a xword a" REGEXP "[[:<:]]word[[:>:]]"; -> 0
mysql> select "weeknights" REGEXP "^(wee|week)(knights|nights)$"; -> 1
Unireg est le constructeur d'interface tty, qui utilise un niveau de connexion très bas aux fichiers NISAM (utilisés par MySQL) et grÅce à ça, il est très rapide. Il existe depuis 1979 (sous Unix en C depuis 1986).
Unireg est constitué de la façon suivante:
convform
. Converti les fichiers `.frm' et les fichiers text d'un jeu de caractère à l'autre.
pack_isam
. Compacte uen table NISAM (réduction de 50 à 80%). La table peut être lue par MySQL comme une table ordinaire.
Seul, un enregistrement doit être décompréssé par acces. Ne gère pas les types BLOB
et TEXT
ou les modifications (pour le moment).
Nous accédons à nos bases de production avec l'interface Unireg et pour servir les pages web via MySQL ( et dans certains cas extremes, le générateur de rapport Unireg).
Unireg prend environs 3Mo sur le disque, et fonctionne au moins sur les OS suivants : SunOS 4.x, Solaris, Linux, HP-UX, ICL Unix, DNIX, SCO et MS-DOS.
Unireg n'est actuellement disponible qu'en suédois et finlandais.
Le prix de Unireg est de 10,000 couronnes suédoies (environs $1500 US), mais cela inclus le support. Unireg est distributé sous la forme d'un binaire. mais toutes les sources ISAM peuvent être trouvées à MySQL). Généralement, nous compilons le binaire pour chaque client, sur son site.
Tous les nouveaux developpement sont concentrés sur MySQL.
MySQL FREE PUBLIC LICENSE (Version 4, March 5, 1995)
Copyright (C) 1995, 1996 TcX AB & Monty Program KB & Detron HB Stockholm SWEDEN, Helsingfors FINLAND and Uppsala SWEDEN All rights reserved.
NOTE: This license is not the same as any of the GNU Licenses published by the Free Software Foundation. Its terms are substantially different from those of the GNU Licenses. If you are familiar with the GNU Licenses, please read this license with extra care.
This License applies to the computer program known as "MySQL". The "Program", below, refers to such program, and a "work based on the Program" means either the Program or any derivative work of the Program, as defined in the United States Copyright Act of 1976, such as a translation or a modification. The Program is a copyrighted work whose copyright is held by TcX Datakonsult AB and Monty Program KB and Detron HB.
This License does not apply when running "MySQL" on any Microsoft operating system. Microsoft operating systems include all versions of Microsoft Windows NT and Microsoft Windows.
BY MODIFYING OR DISTRIBUTING THE PROGRAM (OR ANY WORK BASED ON THE PROGRAM), YOU INDICATE YOUR ACCEPTANCE OF THIS LICENSE TO DO SO, AND ALL ITS TERMS AND CONDITIONS FOR COPYING, DISTRIBUTING OR MODIFYING THE PROGRAM OR WORKS BASED ON IT. NOTHING OTHER THAN THIS LICENSE GRANTS YOU PERMISSION TO MODIFY OR DISTRIBUTE THE PROGRAM OR ITS DERIVATIVE WORKS. THESE ACTIONS ARE PROHIBITED BY LAW. IF YOU DO NOT ACCEPT THESE TERMS AND CONDITIONS, DO NOT MODIFY OR DISTRIBUTE THE PROGRAM.
MySQL shareware license for Microsoft operating systems (Version 1, September 4, 1998)
Copyright (C) 1998 TcX AB & Monty Program KB & Detron HB Stockholm SWEDEN, Helsingfors FINLAND and Uppsala SWEDEN All rights reserved.
This License applies to the computer program known as "MySQL".
This License applies when running MySQL on any Microsoft operating system. Microsoft operating systems include all versions of Microsoft Windows NT and Microsoft Windows.
YOU SHOULD CAREFULLY READ THE FOLLOWING TERMS AND CONDITIONS BEFORE USING, COPYING OR DISTRIBUTING MySQL. BY USING, COPYING AND DISTRIBUTING MySQL, YOU INDICATE YOUR ACCEPTANCE OF THIS LICENSE TO DO SO, AND ALL ITS TERMS AND CONDITIONS FOR USING, COPYING AND DISTRIBUTING MySQL OR WORKS BASED ON IT. NOTHING OTHER THAN THIS LICENSE GRANTS YOU PERMISSION TO USE, COPY OR DISTRIBUTE MySQL OR ITS DERIVATIVE WORKS. THESE ACTIONS ARE PROHIBITED BY LAW. IF YOU DO NOT ACCEPT THESE TERMS AND CONDITIONS, DO NOT USE, COPY OR DISTRIBUTE MySQL.
Postgirot Bank AB 105 06 STOCKHOLM, SWEDEN TCX DataKonsult AB BOX 6434 11382 STOCKHOLM, SWEDEN SWIFT address: PGSI SESS Account number: 96 77 06 - 3Specify: license and/or support and your name and email address. In Europe and Japan, EuroGiro (that should be cheaper) can be used to the same account. If you want to pay by cheque make it payable to "Monty Program KB" and mail it to the address below.
TCX DataKonsult AB BOX 6434 11382 STOCKHOLM, SWEDENFor more information about commercial licensing, please contact:
David Axmark Kungsgatan 65 B 753 21 UPPSALA SWEDEN Voice Phone +46-18-10 22 80 GMT 9-21. Swedish and English spoken Fax +46-8-729 69 05 Email *much* preferred. E-Mail: mysql-licensing@mysql.comFor more about the license prices and commercial support, like email support, please refer to the MySQL manual. 3.5 Licences et couts du support MySQL. 3.6 Types de support commercial. The use of MySQL or any work based on MySQL after the 30-day evaluation period is in violation of international copyright laws.
mysql_affected_rows()
mysql_change_user()
mysql_close()
mysql_connect()
mysql_create_db()
mysql_data_seek()
mysql_debug()
mysql_drop_db()
mysql_dump_debug_info()
mysql_eof()
mysql_errno()
mysql_error()
mysql_escape_string()
mysql_fetch_field()
mysql_fetch_field_direct()
mysql_fetch_fields()
mysql_fetch_lengths()
mysql_fetch_row()
mysql_field_count()
, mysql_field_count()
mysql_field_seek()
mysql_field_tell()
mysql_free_result()
mysql_get_client_info()
mysql_get_host_info()
mysql_get_proto_info()
mysql_get_server_info()
mysql_info()
mysql_init()
mysql_insert_id()
mysql_kill()
mysql_list_dbs()
mysql_list_fields()
mysql_list_processes()
mysql_list_tables()
mysql_num_fields()
mysql_num_rows()
mysql_options()
mysql_ping()
mysql_query()
mysql_real_connect()
mysql_real_query()
mysql_reload()
mysql_row_seek()
mysql_row_tell()
mysql_select_db()
mysql_shutdown()
mysql_stat()
mysql_store_result()
mysql_thread_id()
mysql_use_result()
AUTO_INCREMENT
, et NULL
BLOB
, valeurs par défaut
cc1plus
problèmes
configure
, lancer avant invocation
fatal signal 11
SELECT
et WHERE
isamchk
, isamchk
configure
avant une invocation
make_binary_release
DBI
msql2mysql
mysql
mysql_install_db
mysqlaccess
mysqladmin
, mysqladmin
, mysqladmin
mysqlbug
mysqld
mysqldump
, mysqldump
mysqlimport
, mysqlimport
mysqlshow
NULL
et les valeurs vides
NULL
, et les colonnes AUTO_INCREMENT
NULL
, et les colonnes TIMESTAMP
pack_isam
, pack_isam
, pack_isam
, pack_isam
replace
safe_mysqld
sql_yacc.cc
problèmes
TEXT
, valeurs par défaut
TIMESTAMP
, et NULL
BLOB
et TEXT